| Damon's profiledamon wilder carrPhotosBlogLists | Help |
damon wilder carrdomain dot net team labs
|
|||||||||
|
|
2/11/2009 WCF REST Starter Kit CodePlex Preview 1 Release NotesSoftware is very focused now in terms of the key enabling MSFT inflection points. Silverlight and WCF are the core (all the rest like deep C# 3.0 mastery is simply assumed and boring). The world hires on API but needs to hire on abstraction mastery in real use. Damon Wilder Carr Copyright © 2008 Microsoft Corporation. All rights reserved. This document lists several important notes related to the WCF REST Starter Kit CodePlex Preview 1 Release. Other releases such as the PDC 2008 Media Release may also find some of these notes useful. Please read them before using:
Installation
Configuration
<configuration> <system.serviceModel> <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> </system.serviceModel> </configuration>
Visual Studio
Samples and Documentation
Testing the service (with Fiddler)
Appendix A - Using the Fiddler Test Client
Fiddler is a test Web client that allows you to test Web services by constructing different HTTP requests (GET, POST, and other requests.) and sending it to a URL. Fiddler can be downloaded here.
Fiddler and the ASP .NET Development ServerNote: the newer releases of Fiddler do not require the below configuration, so you may try this approach first – try using http://ipv4.fiddler:(port)/mysite/service.svc directly.If it doesn't work, then use the following configuration steps (the configuration should work in both cases, the above approach is just less configuration). Due to a limitation in the ASP.NET development server and its interaction with external requests to localhost, you must customize Fiddler to work with the ASP.NET development server used in Visual Studio 2008. Open Fiddler, and from the menu, select Rules and then Customize Rules. In the file that opens, find the method called OnBeforeRequest and modify the content under it by pasting the following code.
if (oSession.HostnameIs("MYAPP")) { oSession.host = "127.0.0.1: 53634"; oSession.bypassGateway
=
true;
Note that the number following 127.0.0.1 in the preceding code example, marked in bold large font must match the port number following localhost that the current ASP.NET development server instance is listening on. If you create a different instance of ASP.NET development server while debugging, you must modify the port number here to match the new port number. Save and close the file. Now you use http://myapp/MyService.svc to access your service instead of localhost. If you are working with multiple services launched in different ASP.NET development server instances at the same time, create one such entry for each port number, project or Web site combination, with a different name as shown in the following example code. if (oSession.HostnameIs("MYFOOAPP")) { oSession.host = "127.0.0.1: 53634"; oSession.bypassGateway
=
true;
if (oSession.HostnameIs("MYBARAPP")) { oSession.host = "127.0.0.1: 53123"; oSession.bypassGateway
=
true;
Calling HTTP GET using FiddlerYou would usually not pass in a request body with the GET method. To call HTTP GET on your service using Fiddler, follow the steps shown in Figure 34 (the useful fields are highlighted).
Figure 49 Calling HTTP GET using Fiddler
Figure 50 Inspecting the http GET request and response Calling POST with FiddlerYou would usually pass in a request body to POST that contains the data that you want to post. Calling POST is different from calling GET, because you must pass in a request body. You would do the following things differently (as compared to calling GET) while calling POST before pressing Execute in the response builder:
Figure 36 shows the request builder view and Figure 37 shows the view inspecting the response.
Figure 51 Calling HTTP POST using Fiddler
Figure 52 Inspecting the HTTP POST request and response Calling http PUT using FiddlerYou would usually pass in a request body to a PUT call. The steps to call HTTP PUT are similar to calling POST, except that you select the PUT method instead. Calling http DELETE using FiddlerYou would usually not pass in a request body with DELETE. The steps to call HTTP DELETE are similar to calling GET, except that you select the DELETE method instead.
12/23/2008 Advanced Bidirectional Silverlight 2.0 to ASP.NET Integration – Part 1This is the first post covering techniques for both sending data into your Silverlight environment from ASP.NET as well as getting data out of Silverlight without resorting to a lot of new elements in your architecture. The goal is to use what you already have with the least fuss. You may think you need to resort to ‘pushing’ all data from Silverlight into say a service using WCF but that is not the case in many scenarios. For example, you may have activity which the user creates inside Silverlight 2.0 that results in visual elements you want to send out to ASP.NET for persistence in your ORM environment (where Silverlight has no involvement). From ASP.NET to Silverlight 2.0First, let’s quickly review the easiest way to pass information into your Silverlight control. InitParamatersHere is the on-line help:
We will walk through an entire example of this, including some content that will make sense in how we can move data back out of Silverlight 2.0 to ASP.NET. Code for this ScenarioWe will be using a web UserControl (.ascx) as our control in this example, because as you will see, we need more than just the Silverlight control to make this work. ASCX Host<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="SilverlightInt.ascx.cs" Inherits="SilverlightInt" %> <%@ Register Assembly="System.Web.Silverlight" Namespace="System.Web.UI.SilverlightControls" TagPrefix="asp" %> <asp:Silverlight ID="SilverlightView" runat="server" Source="~/ClientBin/AspNetIntegration.xap" MinimumVersion="2.0.31005.0" /> <asp:TextBox ID="SilverOutput" runat="server" Style="display: none"></asp:TextBox> ASCX Code Behindpublic partial class SilverlightInt : UserControl { [Browsable(true)] public String InitialText { get; set; } protected void Page_Load(object sender, EventArgs e) { SetSilverlightInitParamaters(); } void SetSilverlightInitParamaters() { // Note: We need the client ID for later... var InitParams = new Dictionary<String, String> { { "outputcontrol", SilverOutput.ClientID }, { "InitialText", InitialText ?? "Hello World" } }; SilverlightView.InitParameters = InitParams.ToSilverlightInit(); } } You might notice the extension method ToSilverlightInit(). Here is the code: public static class SilverlightIntegrationExtensions { /// <summary> /// Parse the dictionary into Silverlight format /// for InitParams /// </summary> /// <param name="target">The target.</param> /// <returns></returns> public static String ToSilverlightInit( this IDictionary<String, String> target) { if (target == null) throw new ArgumentNullException("target"); var stringBuffer = new StringBuilder(); foreach(var kvp in target) { if (stringBuffer.Length > 0) stringBuffer.Append(","); // Eliminate case sensitivity stringBuffer.Append(kvp.Key.ToLower() + "=" + kvp.Value); } return stringBuffer.ToString(); } } This is hosted in a normal ASPX page as follows (surrounding detail omitted): <form id="form1" runat="server" style="height: 100%;"> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> <div> <asp:Image Width="300px" ImageUrl="Silverlight_Logo_2.png" runat="server" /> <br /> <asp:Literal ID="sentText" runat="server" /><br /> <hr /> <integrate:SilverlightInt ID="SilverlightInt1" runat="server" InitialText="This is a Test" /> </div> </form> Silverlight Code for Initializationpublic partial class App : Application { public App() { Startup += Application_Startup; UnhandledException += Application_UnhandledException; InitializeComponent(); } void Application_Startup(object sender, StartupEventArgs e) { var PassedInArguments = e.InitParams; RootVisual = new SilverlightView(PassedInArguments); } The interesting parts are that we are accessing the InitParams off the Startup’s ‘e’ object. This is a Dictionary<String,String> which is what prompted the ASP.NET design. Also, we do not use a paramaterless constructor on the initial RootVisual. Instead this is the code: Silverlight View<UserControl x:Class="AspNetIntegration.SilverlightView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid HorizontalAlignment="Left" VerticalAlignment="Top" x:Name="LayoutRoot" Background="Gray"> <Grid.RowDefinitions> <RowDefinition Height="30" /> <RowDefinition Height="30" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="150" /> </Grid.ColumnDefinitions> <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="0" Text="Inside Silverlight" /> <TextBox LostFocus="SendResultBackToAspNet" Grid.Row="1" BorderThickness="2" BorderBrush="Black" x:Name="initialText" /> </Grid> </UserControl> Code Behindpublic partial class SilverlightView : UserControl { readonly IDictionary<string, string> _initParamaters; string _initialText = "Nothing was Passed In - initialtext was empty"; public SilverlightView( IDictionary<string, string> passedInArguments) { _initParamaters = passedInArguments; InitializeComponent(); Loaded += OnLoaded; } void OnLoaded(object sender, RoutedEventArgs e) { SetInitialText(); } void SetInitialText() { if (_initParamaters.ContainsKey("initialtext")) { _initialText = _initParamaters["initialtext"]; } initialText.Text = _initialText; } void SendResultBackToAspNet(object sender, RoutedEventArgs e) { } } Notice the ‘SendResultBackToAspNet’ is empty.. That is coming next and is the tricky part. Coming NextThe code will all be available for download and the much more interesting aspect of sending data back the other way will be presented. Damon del.icio.us Tags: Silverlight,ASP.NET,Bidirectional,Integration,InitParameters,InitParams,HtmlBridge
11/28/2008 C# Delegate Shortcut – No more null testing on events for subscribersThis is fairly well known but I realized I hadn’t seen it blogged about (sorry if already covered). Your likely used to doing this: public event EventHandler<AnimationImageEventArgs> AnimationImageClicked; private void OnClick(object sender, AnimationImageEventArgs e) {
if (AnimationImageClicked != null) AnimationImageClicked(sender, e);
}
No need for that null check. I for one tend to forget them in the bowels of my teams code. What is better then eliminating the issue! This is a way to ‘always have one subscriber’ which you can consider a sort of ‘null object’ pattern implementation for delegates. Checking for null just sucks and I love this kind of ubiquitous removal of it. The first person I saw doing this was Juval Lowy, the master craftsman for basically all things .NET but known recently for utter mastery of WCF in his books and at his firm IDesign. Highly recommend all his writing, code samples and thoughts. public event EventHandler<AnimationImageEventArgs> AnimationImageClicked = delegate { }; private void OnClick(object sender, AnimationImageEventArgs e) {
AnimationImageClicked(sender, e);
}
Damon |
||||||||
|
|