Jeff W. Barnes

Ramblings on C#, WCF, and random .NET

November 2007 - Posts

WCF 3.5: WebInvoke Attribute

A while back, I posted about the WebGet Attribute.  Unfortunately, I never got around to writing about its rather important sibling: WebInvoke Attribute.  While WebGet is completely dedicated to mapping a service operation to an HTTP GET, WebInvoke fills the void for all of the other HTTP methods.  It allows you to map a service operation to all the other HTTP verbs (PUT, POST, DELETE, etc).  Some people, particularly REST enthusiasts, have expressed their disapproval of the terminology because it tends to imply "remote procedure call".  However, WebInvoke simply indicates a service operation is logically an invoke operation. 

Here is a simple example:

[ServiceContract(Namespace = "http://JeffBarnes.Samples.WebInvokeDemo")]
public interface IExampleService
{
    [OperationContract]
    [WebInvoke(
        Method = "POST",
        UriTemplate = "addPhoneNumber?customerID={customerID}&phoneNumber={phoneNumber}")]
    void InsertPhoneNumber(int customerID, string phoneNumber);
}

In this example, there is an operation named InsertPhoneNumber.  It has the usual OperationContract to expose it as an operation for consumers.  However, the WebInvoke attribute has been included as well.  Notice the UriTemplate that allows you do define how the query string parameters can be mapped into the method parameters.  The WCF runtime handles all of the heavy lifting for you.

It should be noted there are several parameters for WebInvoke that mirror WebGet: BodyStyle, RequestFormat, ResponseFormat, and UriTemplate.  I will refrain from going into the details of those parameters since I have already done so in my post on WebGet.  However, there is one parameter in WebInvoke that is not present in WebGet: Method. 

The Method parameter specifies the HTTP verb that corresponds to the operation.  By default, POST is the applied verb unless you specify otherwise.  I only specified POST in the example to be explicit and highlight the parameter does exist, but the behavior would be the same if I had omitted it completely.  The method that you specify in the parameter requires the corresponding HTTP verb in any request that is dispatched to the operation.  For example, if you specify PUT as the method parameter, but the request to the operation uses the POST verb, an exception will be thrown back to the client.

Remember, one of the great things about enabling the web programming model is that it doesn't require a proxy.  Here is a simple example of invoking the operation using System.Net.WebClient:

System.Net.WebClient client = new System.Net.WebClient();

client.UploadString(
    "http://localhost:8000/exampleService/addPhoneNumber?customerID=100&phoneNumber=5555555",
    "POST",
    String.Empty);
Posted: Nov 28 2007, 10:47 PM by jeff.barnes | with 1 comment(s)
Filed under:
ITAC Lunch and Learn for .NET on Dec 4th

ITAC Solutions has organized an upcoming lunch and learn event.  The topic will be "The Future of .NET Development", and I have been asked to deliver the presentation.  This will be a bit different from my typical in-depth technical sessions.  It will be a broad look at where we started, where we are right now, and where we are going in regards to the .NET platform and related technologies.  The goal is to use this initial meeting to paint a picture of the .NET landscape and establish a level of interest among the attendees in order to generate some feedback on the exact material that will be discussed in the future. 

The event will be held on Tuesday, December 4th at at The Emmet O'Neal Library in Crestline Village.  It will be held from 11:30AM until 1PM and lunch will be provided.  The presentation will probably begin shortly before 12PM.  Here is a link to a Google Map of the location.  You can also go to the library web site for detailed driving directions.  Send your registration inquiry to learn@itacsolutionc.com.

There is a strong desire to turn this into a regularly occurring event that will be truly beneficial to the developer community.  So, I would encourage you to make an effort to attend and voice your ideas and opinions.  This type of venue is always exponentially improved with feedback from the community. 

I hope to see you at the event.

How To AJAX Enable a WCF Service

Recently, a friend of mine was picking my brain about the necessary steps for setting up a WCF service that can be invoked from an AJAX client-side script.  Prior to .NET 3.5, this wasn't actually supported by ASP.NET AJAX.  It was only possible to invoke an ASP.NET web service.  Technically, you could still use a WCF service.  Unfortunately, it had to be wrapped by an ASP.NET web service.  Anyway, this seemed like a good blog post to make in honor of Visual Studio 2008 and .NET 3.5 officially going RTM earlier today!

From WCF's perspective, there is very little additional work required to enable AJAX requests.  For the most part, it can actually be enabled via configuration.  There is a new endpoint behavior and a new binding that take care of the heavy lifting.

WebScriptEnablingBehavior
This is an endpoint behavior that enables a javascript proxy endpoint.  It enables the HTTP programming model for dispatching operations based on a URI templates and provides support for HTTP verb selection (aka RESTful services). 

WebHttpBinding
This is a new binding that goes hand in hand with the WebScriptEnablingBehavior.  It is required in order for WebScriptEnablingBehavior to function.  The binding uses a new message encoder that enables plain old xml (POX) messaging rather than SOAP based messaging.  To really leverage the potential of this binding, you need to apply the new WebGet and WebInvoke attributes to the applicable service operations.

Below, I have included a configuration example for an WCF service hosted in IIS to give you a bit of an illustration.  However, the same thing can be achieved programmatically (if desired).

<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceDebug includeExceptionDetailInFaults="true"/>
          <serviceMetadata httpGetEnabled="true"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="EndpointBehavior">
          <enableWebScript />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
    <services>
      <service name="WeatherService" behaviorConfiguration="ServiceBehavior">
        <endpoint address="" behaviorConfiguration="EndpointBehavior"
            binding="webHttpBinding" contract="IWeatherService" />
      </service>
    </services>
  </system.serviceModel>
</configuration>

After enabling AJAX requests, you can generate a javascript proxy for your client by browsing to http://localhost/myWebApp/WeatherService.svc/js (based on the configuration example).  You can then use the ASP.NET AJAX ScriptManager to supply a ScriptReference to the javascript proxy:

<asp:ScriptManager ID="ScriptManager1" runat="server">
   <Scripts>
      <asp:ScriptReference Path="~/WeatherService.js" />
   </Scripts>
</asp:ScriptManager>

There is an alternative approach as well.  Instead of adding a script reference, you can add a service reference.  However, it is important to set the InlineScript attribute to false.  WCF services aren't compatible with the InlineScript attribute set to true.

<asp:ScriptManager ID="ScriptManager1" runat="server">
   <Services>
      <asp:ServiceReference InlineScript="false" Path="~/WeatherService.svc" />
   </Services>
</asp:ScriptManager>   

I have a simple demo that you can download here to get a better idea of the big picture.

Posted: Nov 19 2007, 10:17 PM by jeff.barnes | with 2 comment(s)
Filed under: ,
Silverlight .NET University in Huntsville

Sujata Devraj of the Huntsville New Technology Users Group asked me to pass the word along about an upcoming event.  On Tuesday, November 13th and Monday, November 19th, their user group will be hosting a two-part run of .NET University - Silverlight Edition.  It will run from 6PM to 9PM on both nights.  There will be a Zune to give away on the last night, but, as I understand it, you must be present both nights to win.

The speakers will be Doug Turnure (Microsoft Developer Evangelist), Jesse Liberty (Microsoft Senior Program Manager, Silverlight Development Team), and my good friend Todd Miranda (Chief Information Security Officer of Softech Development).  If you are interested in Silverlight, this will be an excellent opportunity to get some free training.  I would encourage you to attend if you will be in the area of feel up for making the drive.

Community Credit Winner for October 2007

Earlier this evening, I was notified that I  won 4th place in the October 2007 contest for Community Credit

In case you aren't familiar with Community Credit, it is a site operated by David Silverlight with the sole purpose of rewarding people actively involved in the developer community.  Essentially, people compete each month to earn points by blogging, attending technical events, giving technical presentations, participating in forums, etc.  Those with the highest number of points each month win a prize.  It is an awesome way to encourage community involvement.  To make things even more interesting, Community Credit is popular for the motto: "We give stupid prizes to smart people."  I love the wacky variety of prizes that are given out each month.

This time I won the Plasma Light Disk.  (Yes, I am a complete geek!)  Here is the excerpt and image from Community Credit:

Pocket Plasma Light Disk energizes wardrobe
With a Pocket Plasma Light Disk clipped to your pocket, belt, purse, hat or anywhere you need to add a little energy. Uses super bright LED technology and microchip circuitry to create an amazing light show in response to touch or sound that makes the light "dance”.

Posted: Nov 01 2007, 11:18 PM by jeff.barnes | with no comments
Filed under:


Disclaimer:The opinions and views expressed within this blog are solely my own and do not represent those of my employer or anyone else.