I'm Keyvan Nayyeri, a 28 years old software engineer working at Match.Com and living in Dallas, Texas.
I have a Master’s degree in computer science and a bachelor's degree in applied mathematics. I’m also known to be a technical author with several technical publications in the form of books and articles. Besides, I'm an open source enthusiast and have coordinated or contributed to several projects. Currently, I maintain my projects on GitHub.
As a content provider on the internet, not only I publish on this technical blog, but also I'm a podcaster and publish audio podcasts on Mash This.
Trying to maintain a healthy and active lifestyle, I'm a pescetarianist and exercise almost everyday. I’m an avid runner, soccer defender, and tennis player. I also have an interest in fashion.
Fiddler is one of the common tools for .NET developers especially for ASP.NET developers who try to debug their HTTP requests and responses.
But Fiddler is a more general product for debugging any HTTP request and response. So this great tool can be used for testing any hosted site or service. Here I want to show you how you can use Fiddler to test RESTful Windows Communication Foundation services in .NET 3.5 (or 3.0).
I don't want to step in details of creating a RESTful WCF service. .NET 3.5 introduces WebHttpBinding as a new binding to build RESTful services in WCF and this has made the process pretty easy and fast.
First let me develop a very simple RESTful service with WCF 3.5. This service has two methods. One is a simple function that returns a string value based on an HTTP GET verb and the other is a function that returns a string based on HTTP PUT verb and the data that is passed to it.
This sample service has two methods (GetData and PutData) that get a name via the URI and use it in their internal processing. The second method also gets some details about the contact via the data that is passed to it via PUT verb. The interface for the service is pretty simple: two methods for GET and PUT verbs and a data contract class. Here is the code for the interface:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Web;
namespace FiddlerWCFSample
{
[ServiceContract(Namespace = "api.nayyeri.net")]
public interface IRESTService
{
[OperationContract]
[WebGet(UriTemplate = "api/{name}/",
ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Bare,
RequestFormat = WebMessageFormat.Xml)]
string GetData(string name);
[OperationContract]
[WebInvoke(Method = "PUT",
UriTemplate = "api/{name}/",
ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Bare,
RequestFormat = WebMessageFormat.Xml)]
string PutData(string name, ContactDetails details);
}
[DataContract(Name = "ContactDetails", Namespace = "")]
public class ContactDetails
{
[DataMember(IsRequired = true)]
public string SiteUrl { get; set; }
}
}
The service implementation is even simpler than this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace FiddlerWCFSample
{
public class RESTService : IRESTService
{
#region IRESTService Members
public string GetData(string name)
{
return string.Format("Hello {0}!", name);
}
public string PutData(string name, ContactDetails details)
{
return string.Format("Hello {0} ({1})!", name, details.SiteUrl);
}
#endregion
}
}
And there is nothing else for the service implementation!
Without a good HTTP rewriting mechanism the RESTful service doesn't look good so I also write an IIS 7.0 module to rewrite all incoming requests to the service file.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
namespace FiddlerWCFSample
{
public class RewriterModule : IHttpModule
{
#region IHttpModule Members
void IHttpModule.Dispose()
{
return;
}
void IHttpModule.Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
}
void context_BeginRequest(object sender, EventArgs e)
{
HttpContext context = ((HttpApplication)sender).Context;
string requestPath = context.Request.Path.ToLower();
if (requestPath.Contains(".svc"))
return;
context.Request.Headers.Add("X-REWRITE-URL", context.Request.Url.AbsolutePath);
context.RewritePath("~/service.svc", requestPath.Replace("/sampleservice", ""),
context.Request.QueryString.ToString(), false);
}
#endregion
}
}
The last step before testing the service, as you know, is configuring and hosting the service. Configuring a RESTful WCF service requires the usage of WebHttpBinding. Below is the basic configuration that I used for my service. Note that you can also self-host the service but IIS hosting is a more common case for RESTful services on production.
xml version="1.0"?>
<configuration>
<system.serviceModel>
<services>
<service name="FiddlerWCFSample.RESTService"
behaviorConfiguration="MetadataBehavior">
<endpoint address="" behaviorConfiguration="WebBehavior"
binding="webHttpBinding"
contract="FiddlerWCFSample.IRESTService"/>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
service>
services>
<behaviors>
<endpointBehaviors>
<behavior name="WebBehavior">
<webHttp />
behavior>
endpointBehaviors>
<serviceBehaviors>
<behavior name="MetadataBehavior">
<serviceMetadata httpGetEnabled="true" httpGetUrl="" />
behavior>
serviceBehaviors>
behaviors>
system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="UrlRewriter" type="FiddlerWCFSample.RewriterModule, FiddlerWCFSample" />
modules>
system.webServer>
configuration>
Alright! Now we're on the point that this post is trying to cover. Testing a RESTful WCF service, especially for some HTTP verbs like PUT, requires some extra effort to be able to build your request data and PUT them on the server. There are different ways to do this and one of them is writing your own code to use an HTTP client to put the data on the server.
For an HTTP GET verb method, test would be easy. You enter the URL in your browser and test the method as I do for my GetData method.
But what about a PUT verb method? There is an easy and fast way to do this via Fiddler that I'm going to show you.
To test the GetData method with Fiddler, I can use the Request Builder tab to build a request to the appropriate URL with GET method and then execute my request.
After executing the request, I get a 200 success status from the server. If I navigate to Session Inspector tab and open TextView then I'm able to see the XML response from the server.
But for a PUT verb method, like PutData in my example, you need to do some more work when building your request. After choosing the correct URL for your request in Request Builder tab, you need to choose the PUT verb method from the left drop down list as well.
The next step is to write the request body by hand. In my example, I have to write the XML code text by hand. The last point, which is very important, is to set the Content-Type request header of your request to the XML MIME type which is "application/xml". Note that this is for my example with XML requests but you would need to use another text type for Json requests.
After executing this request I get the response that I expected to get.
That's it! I found that using Fiddler is one of the best and even the best way to test a RESTful WCF service quickly and easily.
I uploaded the source code sample for this post here so you can download the code and test it for your own.
Bill
Dec 17, 2008 8:11 AM
#
Great example. Very clear and understandable. Outstanding
Anthony
Jan 19, 2009 3:07 PM
#
I have been implementing a WCF Restful application. All the GET methods works great, but when testing the "POST" request I'm getting the following error:
The server encountered an error processing the request. The exception message is 'Unable to deserialize XML body with root name 'User' and root namespace '' (for operation 'PostUser' and contract ('IUserManager', 'http://tempuri.org/')) using DataContractSerializer.
This is my service method I'm calling:
[OperationContract]
[WebInvoke(Method="POST", UriTemplate = "users", ResponseFormat = WebMessageFormat.Xml, BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml)]
string PostUser(User newUser);
Here's my DataContract for the "User" object:
[DataContract(Name = "User", Namespace = "WCFPlusRest")]
[Serializable]
public class User
{
[DataMember(IsRequired = true)]
public string Username { get; set; }
[DataMember(IsRequired = true)]
public string FirstName { get; set; }
[DataMember(IsRequired = true)]
public string LastName { get; set; }
[DataMember(IsRequired = true)]
public string Role { get; set; }
[DataMember(IsRequired = true)]
public List<string> Hobbies { get; set; }
}
And when doing the request using fiddler:
POST /WcfPlusRest/UserManager/rest/users HTTP/1.1
User-Agent: Fiddler
Host: localhost:8731
Content-Type: application/xml
Content-Length: 245
<User>
<Username>rperez</username>
<FirstName>Robert</firstName>
<LastName>Perez</lastName>
<Role>Designer</role>
<Hobbies>
<Hobbie>Party</hobbie>
<Hobbie>travel</hobbie>
<Hobbie>Sing</hobbie>
</Hobbies>
</User>
I have been looking for a solution for a couple of days but I can't find any answer. Do you have any idea of what I might be doing wrong? The problem seems to be when trying to parse and serialize the XML sent into an "User" object, but it should be working according to your post.
Thanks
-aB
Robert Edwards
Feb 04, 2009 8:42 PM
#
Anthony -
It might have something to do with your properties. Give them an explicit name [DataMember(Name="UserName")]
That helped me.
Robert Edwards
Feb 04, 2009 9:26 PM
#
Also, your xml should have the namespace you're using:
<User xmlns="WCFPlusRest">
...
</User>
Des
Feb 07, 2010 2:54 AM
#
Good article, for URL rewriting you can check out Helicon's URL rewriter: http://www.isapirewrite.com/
John
Mar 03, 2010 6:59 PM
#
I'm trying to use the Telligent API V2. I followed the steps mentioned in http://telligent.com/community/developers/w/wiki/rest-api-troubleshooting.aspx and I know the setup is correct because I'm able to access domain/api.ashx/v2/wikis/12/toc.xml from the browser (provided I'm logged in). If I try the same domain/api.ashx/v2/wikis/27/toc.xml using fiddler I get 401 error. I'm setting Rest-User-Token:64Bitencoded(apikey:uname) . what could be wrong? Thanks in advance
pankaj
Apr 06, 2010 5:09 AM
#
the sample code has been removed. Can u please reload or mail me the sample code for the current application. I am in urgent need.
Thanks
hamsa_santi@yahoo.com
Sep 21, 2010 6:59 PM
#
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable." Can you please re upload it or send it to me. Thanks
Russell Thackston
Sep 29, 2010 9:33 AM
#
json
Apr 26, 2011 12:36 PM
#
Jordi
May 08, 2012 6:05 AM
#
I've used Fiddler a lot too ! :)
Hope you find interesting this post talking about WCF automated testing:
http://jordi-montana.blogspot.com.es/2012/03/testing-wcf-restful-services-with-post.html
Thanks!
Mitesh
Dec 18, 2012 3:30 PM
#
I am not able to see images on the page -- http://keyvan.io/use-fiddler-to-test-restful-wcf-services
I am interested in seeing the fiddler - PUT request. can you email these images to my personal email id - miteshvmehta@gmail.com
Thanks,
Mitesh
Leave a Comment