New Dime Cast: Migrating from .asmx web services to WCF web services

by Donn Felker 30. December 2008 07:29

Woo hoo! I created another Dime Cast and its up and running today!

Learn how to migrate from your old asmx web services to new fancy WCF web services.

Check it out here

dynomite 

 

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

WCF

Intro to WCF Screen Cast Now Available

by Donn Felker 16. December 2008 03:48

I have a new Screen cast available on  DimeCasts.net. It is entitled "Introduction to WCF: Creating your first Service".

In this episode we will take a look at how to create your first WCF service. We will first walk you though the ABCs of what a WCF service is, we will then show you step by step how you can create a service.

Click here to watch.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

WCF

How To: REST Services in WCF 3.5 Part 2 - The POST

by Donn Felker 3. December 2008 17:29

This post is part of a series.

 

Implementing a POST HTTP Verb Call

In this post we're going to cover what it takes to implement a PUT into our REST Service that we defined in Part 1 of this series.

First of all, what is the POST HTTP verb for? To understand this lets take a look at how a HTTP Get call is formed from an HTTP Header perspective. A GET request fetches data from a web server based solely on a URL value and a set of HTTP headers.

HTTP GET Header Example:

GET /index.html?userid=joe&password=guessme HTTP/1.1
Host: www.example.org
User-Agent: Mozilla/4.0

In this example the Get requests from a host (www.example.org) with the Mozilla/4.0 type browser and is asking for the index.html page with the query string values userid and password (and their corresponding values).

Now for the HTTP POST... POST request sends additional data to the web server, specified after the URL, the headers, and a blank line to indicate the end of the headers. An example:

POST /login.aspx HTTP/1.1
Host: www.example.org
User-Agent: Mozilla/4.0
Content-Length: 27
Content-Type: application/x-www-form-urlencoded

userid=joe&password=guessme

 

At a very simple level - A POST is normally done from a web form. When we fill out a form and send the data the form attribute "method" is set to "post".

If you want the super formal explanation of POST check out the POST definition on the W3C site.

 

The implementation in WCF

In the previous example we used a simple Gas Price Service. This next service is something a little different. Lets assume that we have a comedy web site that allows users to get "insults" and "save insults". We are going to use this example, and its called the "Insult Service". Its a very simple REST service that insults you or your co-workers or anyone else for that matter. Kind of fun to mess around with. This version of the insult service has the following methods:

  • GET: Insult someone (an exact copy of the previous part 1, just in a different context)
  • POST: Add a new insult

To receive an insult we ask the insult service to insult someone via the GET (again, this is the same as the previous example).You would call the service like this: http://localhost:7000/insult/{personsNameToInsult}  .

NOTE: The insult service grabs a random insult from a list of insults and returns it to the user.

Here it is in action: Replace {personsNameToInsult} with "Donn" (minus the quotes)

image 

Here is the GET in code from the WCF Service Contract:

 

[OperationContract]
[WebGet(RequestFormat = WebMessageFormat.Xml,
	ResponseFormat = WebMessageFormat.Xml,
	BodyStyle = WebMessageBodyStyle.Bare,
	UriTemplate = "/insult/{personToInsult}")]
Insult GetInsult(string personToInsult);

 

Now, to implement the POST we need a way to tell the server that we want to POST data to a service. Here's how we do it in WCF:

 

[OperationContract]
[WebInvoke(RequestFormat = WebMessageFormat.Xml,
	ResponseFormat = WebMessageFormat.Xml,
	BodyStyle = WebMessageBodyStyle.Bare,
	UriTemplate = "/insult/Add/{insultName}/{insultText}", 
	Method = "POST")]
void AddInsult(string insultName, string insultText);
In this service contract we are telling WCF that the URITemplate is going to be as such:
/insult/Add/{insultName}/{insultText}
Where {insultName} and {insultText} map to the string values in the "AddInsult" method. To add an insult we'd have a POST request that looks like this:
http://localhost:7000/insult/Add/TestInsult/This+is+a+test+insult
However, if we type this into the Browser window we will get the following:

image

This is because the web browser by default performs a GET operation on the URI that is posted into the address bar.

So how do we POST? We can either build a web form to do it for us, or we can use a web debugging tool.

 

Adding a New Insult: The POST

Since we do not have a web front end for this service we need to construct a HTTP POST manually. We can do this with Fiddler. Fiddler is a Web Debugging tool that allows you to inspect HTTP Traffic and construct requests. We're going to use it for constructing our POST call. (You could also create a simple web form to do this as well).

Constructing the POST:

  1. Install Fiddler
  2. Open Fiddler
  3. Open the request builder
  4. Select Post
  5. Build the request
  6. Submit the request

...

3. Open the request builder

image

 

4. Select POST

image

 

5. Build The Request

 image

Like this:

image

 

6. Submit the request

image

At this point our service has been called and the values have been written to the data repository (db or file, etc).

Now lets see if the insult shows up in our service. Lets hit refresh on our GET page a few times to see if it shows up. Which it should.

image

 

Conclusion

As you can see, its fairly simple to implement a POST action to add new values to a WCF REST service. This has been done utilizing the WebInvokeAttribute to handle our POST action.

Additional Reading:

 

Download Code

Part2.zip (~11kb)

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

WCF

SVCUtil & VS2008

by Donn Felker 2. December 2008 05:56

After some research into a Service Reference problem I was having with Silverlight I came to find out (but not officially) that VS2008 DOES NOT use SvcUtil under the hood to get its service reference. It uses its own internal implementation of a proxy generation tool. I'll have to confirm this conclusion with some authority/book/etc, but if this is the case, I made a statement in Dime Cast 67 (WCF Rest Part 1) that informed viewers that VS2008 uses SVCUtil under the hood.

I'll see what I can find out and post it back here when I confirm my thoughts.

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

WCF

Dime Cast on RESTful WCF

by Donn Felker 2. December 2008 05:31

I recently created a small 10 minute recording on how to create a WCF RESTful service. This screen cast has been published on Dime Casts .NET here. This is part 1 of the series in which I go into how to create a WebGet based WCF RESTful service. This screen cast is a video extension of the post I wrote here.  At a high level, this screen cast is an introduction to the RESTful capabilities of WCF. In another future (yet to be recorded) Dime Cast I will go into how to utilize WebInvoke attribute to perform POST operations against the REST web service.

 

Click here to watch, or click on the image below.

 

DimeCastsLogoMaster

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Screencasts | WCF

Silverlight Cross Domain Issue

by Donn Felker 12. November 2008 07:31

I'm doing some Silverlight Development and I ran into a wacky issue (or so it seemed at the time).

The Silverlight app would connect to a Java Web Service and get some data (XML). The end result is that this Silverlight app will talk to Java Web Services and the xap file sit on a java web server and be downloaded to the client. During development its done on Windows Machines/VM's (of course). However, when we connected to the service, it would bomb with a Security Exception as follows:

 

A first chance exception of type 'System.ServiceModel.CommunicationException' occurred in System.ServiceModel.dll

Additional information: An error occurred while trying to make a request to URI 'http://example.org:7001/beans/TestWebServiceBean'. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. Please see the inner exception for more details.

At first glance this looks like an issue with the services clientaccesspolicy.xml file. But looking at the requests through fiddler or Web Dev Helper we can see that an HTTP success (200) was occurring for the requests of those files. They were coming back as expected.

 

CAS: True Smoke and Mirrors

The problem was due to the fact that we running Silverlight under the Test html page from the file system. So it would look something like this:

C:\SVNHome\path\to\project\Bin\Debug\TestPage.html

The Silverlight app would call a web service on the network or Internet. Them, BOOM all hell would break loose. Security exceptions flying around like snowflakes in Minnesnowta.

It looks like this was an issue with Code Access Security. Now I'm not exactly 100% sure where in the CAS stack this error occurred, but I do know that the local file was in a different zone than the Internet zone and when executing code in different zones you run into tons of CAS issues (SecurityExceptions). <Sarcasm>Read more about the super exciting world of CAS here </Sarcasm>. 


So I created a ASP.NET Web App and linked the Silverlight app with the Web App. I fired up the test page which now looks like this:

http://localhost:3399/SilverlightApplicationWevSvcTestTestPage.aspx

BOOM! The app worked just like it should have. Looks like a definite culprit of the deadly CAS. :)

:)

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Silverlight | WCF

How To: Implement a simple REST Services in WCF 3.5 Part 1

by Donn Felker 3. November 2008 11:03

What is REST?

A REST web service is a service that embraces "Representational State Transfer". What does this mean? Lets take a gander at the Wikipedia entry:

...

REST strictly refers to a collection of network architecture principles which outline how resources are defined and addressed. The term is often used in a looser sense to describe any simple interface which transmits domain-specific data over HTTP without an additional messaging layer such as SOAP or session tracking via HTTP cookies.

... (Source)

 

A simple ScreenCast illustrates this the best:

image

 

A Simple Example of REST Services

If I were using a REST service I would go to http://www.example.com/GetGasPrice/For/Zipcode/55402/ and the response would be a small POX (Plain old Xml) chunk that represents the price of gas at ZipCode 55402. Replace the "55402" with "96032" and you'll get the gas price for zipcode 96032.

Here is what we would see on the screen:

image

Plain Ol' Xml is being returned for our query. I can use .NET, PHP, C++, Ruby, Java, you name it, and we could parse this and move on with our application. REST is very interoperable.

 

This type of URL Scheming is very easy for users to understand as its following a Representational format. We're representing what we want to do in the form of the Uri. It's simple and easy to read. I can even access it via my web browser! We can change the zipcode from 55402 to 55401 and get a different price behind the scenes. Awesome.

However, this is not the only benefit of REST. There are many benefits of REST which are well beyond the scope of this introductory article. To learn more, read the wikipedia entry. In this article We're going to cover HOW to implement a rest service in WCF 3.5.

 

How To Implement REST Services

Note: If you want to go straight to the code, scroll down a bit. The full code project is zipped up and also available for download as well at the bottom of the post.

 

The Web Programming Model

We will cover the most common and basic use of a REST service, the GET. However, we will glance over the other topics as well.

WCF Provides a REST Programming model for us to use . The following classes are of great intestest when programming REST services. 

 

WebGetAttribute 

The WebGet attribute allows us to specify how we want to handle GET HTTP Verbs for processing the REST service. As the examples shows,  we are performing a GET on the URL and we're expecting some POX results back.

The code for that WCF Operation Contract looks like this:

 

        [OperationContract]
        [WebGet
            (RequestFormat = WebMessageFormat.Xml,
            ResponseFormat = WebMessageFormat.Xml,
            BodyStyle = WebMessageBodyStyle.Bare,
            UriTemplate = "/GetGasPrice/For/ZipCode/{zipCode}"
            )]
        GasPriceData GetPriceData(string zipCode);

 

RequestFormat is the format the request is made in. the two options are XML and JSON. If you request from the browser your request will still be honored.

ResponseFormat is the format that will be returned. The two options are XML and JSON. Here we are specifying that we would like to have XML returned to us.

BodyStyle represents how we want the data returned. Do we want the bare XML or the full "wrapped" XML?

Bare: 

<GasPriceData>
    <GasStation>Super America</GasStation>
    <Price>2.05</Price>
</GasPriceData>

Wrapped:

<GetPriceDataResponse>
    <GetPriceDataResult>
        <a:GasStation>Super America</a:GasStation>
        <a:Price>2.05</a:Price>
    </GetPriceDataResult>
</GetPriceDataResponse>

UriTemplate describes how we are going to handle the Uri mapping. In this case we are stating that from the BaseAddress we are going to have a url that looks like the following: /GetGasPrice/For/ZipCode/{zipCode}. This Uri is going to map to the method "GetPriceData(string zipCode)". The varibale in the UriTemplate - "{zipCode}" maps to the parameter in the method which is also called "zipCode". We have now abstracted our method call to utilize a Representational format of Uri.

If we wanted, we could change the UriTemplate to something like this: "/GetGasPrice/For/Some/Other/Long/Path/To/The/ZipCode/{zipCode}" and in the URL of your service you would access it like this:

- http://www.example.com/GetGasPrice/For/Some/Long/Path/To/The/ZipCode/55402

This would execute the GetPriceData method at this location.

 

WebHttpBinding - This is best put by the MSDN doc, so I'm going to quote them:

The WebHttpBinding incorporates support for XML, JSON, and raw binary data using the WebMessageEncodingBindingElement. It is composed of an HttpsTransportBindingElement, an HttpTransportBindingElement and a WebHttpSecurity object. The WebHttpBinding is designed to be used in conjunction with the WebHttpBehavior.

WebServiceHost - Another one that the MSDN doc covers better than I could:

WebServiceHost extends the ServiceHost to make it easier to host a non-SOAP Web-style service. If WebServiceHost finds no endpoints in the service description, it automatically creates a default endpoint at the service's base address. When creating a default HTTP endpoint, the WebServiceHost also disables the HTTP Help page and the Web Services Description Language (WSDL) GET functionality so the metadata endpoint does not interfere with the default HTTP endpoint. WebServiceHost also ensures that all endpoints that use WebHttpBinding have the required WebHttpBehavior attached. Finally, WebServiceHost automatically configures the endpoint's binding to work with the associated Internet Information Services (IIS) security settings when used in a secure virtual directory.

 

The Code

IGasPriceService.cs

using System.ServiceModel;
using System.ServiceModel.Web;
using Part1.GasService;

namespace Part1.GasService
{
    [ServiceContract]
    public interface IGasPriceService
    {
        [OperationContract]
        [WebGet
            (ResponseFormat = WebMessageFormat.Xml,
            BodyStyle = WebMessageBodyStyle.Bare,
            UriTemplate = "/GetGasPrice/For/ZipCode/{zipCode}"
            )]
        GasPriceData GetPriceData(string zipCode);

        [OperationContract]
        [WebGet
            (RequestFormat = WebMessageFormat.Xml,
            ResponseFormat = WebMessageFormat.Xml,
            BodyStyle = WebMessageBodyStyle.Bare,
            UriTemplate = "/GetGasPrice/For/City/{city}"
            )]
        GasPriceData GetPriceDataForCity(string city);
    }
}

This code explained ...

This is the Service Contract which implements two methods for our REST service. One that will get gas prices by city name and one that will get it by ZipCode.

 

GasPriceService.cs

using Part1.GasService;

namespace Part1.GasService
{
    public class GasPriceService : IGasPriceService
    {
        #region IGasPriceService Members

        public GasPriceData GetPriceData(string zipCode)
        {
            switch (zipCode)
            {
                case "00000":
                    return new GasPriceData { GasStation = "None", Price = 0.00m };
                case "55410":
                    return new GasPriceData {GasStation = "Holiday", Price = 1.99m};
                case "55404":
                    return new GasPriceData {GasStation = "Costco", Price = 1.79m};
                case "55412":
                    return new GasPriceData {GasStation = "Sams Club", Price = 2.79m};
                default:
                    return new GasPriceData {GasStation = "Super America", Price = 2.05m};
            }
        }

        public GasPriceData GetPriceDataForCity(string city)
        {
            switch (city.ToLower())
            {
                case "minneapolis":
                    return new GasPriceData { GasStation = "Super America", Price = 1.87m };
                case "stpaul":
                    return new GasPriceData { GasStation = "Holiday", Price = 1.99m };
                case "edina":
                    return new GasPriceData { GasStation = "Costco", Price = 1.79m };
                case "bloomington":
                case "richfield":
                case "woodbury":
                    return new GasPriceData { GasStation = "Sams Club", Price = 2.79m };
                case "shakopee":
                    return new GasPriceData { GasStation = "BP", Price = 4.39m };
                default:
                    return new GasPriceData { GasStation = "Super America", Price = 2.05m };
            }
        }

        #endregion
    }
}

This code explained ...

This is a quick hack to get data back to the service. In a real world scenario this would connect to some data store which would return the data. You would also probably want to cache this data for a short period of time to allow for more throughput throughout your system.

 

GasPriceData.cs

using System.Runtime.Serialization;

namespace Part1.GasService
{
    [DataContract]
    public class GasPriceData
    {
        [DataMember]
        public string GasStation { get; set; }

        [DataMember]
        public decimal Price { get; set; }
    }
}

This code explained ...  

This is the complex type that represents the Gas Price Data itself. Again, in a real service this would be implemented as a more robust object model. This is for example purposes only.

 

ExampleWebHost.cs

using System;
using System.ServiceModel.Web;
using Part1.GasService;

namespace Part1
{
    public class ExampleWebHost
    {
        public static void Main()
        {
            using (var gasPriceServiceHost = new WebServiceHost(typeof (GasPriceService)))
            {
                gasPriceServiceHost.Open();

                Console.WriteLine("The Base Address for the Gas Price Service is: {0}",gasPriceServiceHost.BaseAddresses[0].AbsoluteUri);
                Console.WriteLine("The service is now active. To terminate, press .");

                Console.ReadLine();
            }
        }
    }
}

This code explained ...

This code self hosts the WCF service and waits for a user to terminate it in a console window.

app.config



  
    
      
      
        
          
            
          
        
        
      
    
  

 

 

This code explained ...  

We are merely setting a base address and telling WCF to use the WebHttpBinding. The WebServiceHost takes care of the remaining config GOO that we would normally have to deal with. (how nice).


Starting Up The Service

Make sure your service is set to start as a console app and start up a new instance. At this time you should be able to access the REST service from your local host by sending a command to it like this:

image

The base address is "http://localhost:7002/ and then the UriTemplate is appended to that, making the full REST URL.

Clicking Enter, you will get your XML results. :)

 

Possibilities: Extending your Solution

As you've seen in the code, you can also implement extend your functionality in REST services by allowing users to find the gas price for a given city:

image

 

Conclusion

It's fairly simple to implement a WCF REST Service. Simply use the WebGet attribute, the Web Service host and the binding and you're off to the races. Next topic: Other HTTP Verbs with WCF Rest Services (Part 2).

 

Downloads

Project File and Classes Part1.zip (~8.5kb)

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

WCF

Disabling/Turn off the WcfSvcHost Test Client in VS2008

by Donn Felker 2. November 2008 14:16

This pertains to non-sp1. If you have SP1 installed there "should" be an option to disable it in the gui. This is from what I've read on the web. I don't have an SP1 machine in front of me so I'm posting this so I can find it later. If it helps you, then hallelujah

Here is what the test client looks like in your tray when it starts:

image

 

To disable the Test WCF Client (WcfTestClient.exe / WcfSvcHost) that comes with VS2008 you have to edit the goop that is the Project file.

Delete the following GUID from the PropertyGroup as shown below: {3D9AD99F-2412-4246-B90B-4EAA41C64699}

 

image

If you have the project open in Visual Studio it will ask you to reload it. Reload the project and you should be able to use whatever your service host implementation is.

Doing this will turn off the default test client. This was VERY problematic for me today while doing some proof of concept WCF REST implementations.

 

More on the WCF REST stuff soon. I can't believe how simple it is. The examples I found were not too intiutive so I'll type up a quick and easy tutorial that covers the GET and PUT http verbs.

Coming soon!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

WCF

How Can You Learn WCF?

by Donn Felker 2. November 2008 01:27

When I present at conferences and consult at clients I often get asked "How can I learn WCF?" It's a great question because WCF in itself is a beast (as is WPF and Silverlight, etc).

When I first started with WCF I tried learning via Internet tutorials, browsing the MSDN, looking at magazines, etc. While some of the articles did help I never really grasped the concept of what WCF was presenting until I picked up a couple of books. At that point it hit home (literally within an hour of reading Learning WCF).

 

Book Complexity

The books below are listed IN ORDER because if you read them in that order they will make more sense. Michele Bustamante's book leans more towards the "WCF Newbie" while Juval Lowy's book tends towards the user that has some SOA experience already and is looking to ramp up on WCF. But Lowy's book also goes into more detail at time which is why its also handy to have on your shelf even if you area a beginner. Example: At times Bustamante's book will cover a topic but if you need more on it, crack open Lowy's.

Please Note Though: Lowy does not cover Integrated MSMQ and Federated Security. If you're looking for that, look at Bustamante's book. Bustamate has about 15 pages on Federated Security. But she only has 1 page on Integrated MSMQ.

If you're still wondering what book to buy, here's the complexity chart as a I see it. (IMO) Hopefully this picture speaks 1000 words.

wcfBookComplexity

 

Here are the actual books and the links to Amazon if you want to read the reviews and what not.

Step 1: Learning WCF (Bustamante)

 LearningWCF

Step 2: Programming WCF (Lowy)

 ProgrammingWCF

 

While this may be my own best method for learning WCF - I have recommended it to a couple colleagues and they've had good results so it must have some validity. (I hope.) :)

 

Good luck!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

WCF

Twin Cities Code Camp Presentation and Code

by Donn Felker 13. October 2008 03:41

As I promised, here is the full source and presentation for this weekends presentation at the Twin Cities Code Camp.

The talk was entitled:

Smooth Operator: Using the Workflow Rules Engine within WCF

Ever changing business logic requires rule systems that are flexible to business demands. The majority of the time the business requires that these rules systems must be consumable by other applications. Come see how we can utilize the Rules Engine within Windows Workflow Foundation to evaluate our rules and simplify our rules configuration. We will then encompass this functionality within a Windows Communication Foundation Service which will enable consumers to utilize the service.

Download the Code Here (7.75 MB)

Download the Presentation (337kb)

 

A big thanks to Jason Bock for setting up such a successful code camp. Be sure to check out the Twin Cities Code Camp web site for new event information. The event is moving to a LARGER location in April 2009!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Events | WCF

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen

About the author

Donn Felker

Senior Consultant
MCTS
ScrumMaster
Agile Practitioner

About Me | Books I Recommend

Gotta Pay The Bills


Tag cloud

    Popular Posts

    RecentComments

    Comment RSS

    Calendar

    <<  January 2009  >>
    MoTuWeThFrSaSu
    2930311234
    567891011
    12131415161718
    19202122232425
    2627282930311
    2345678

    View posts in large calendar