Omair Shakeel

Thursday, March 18, 2010

Debugging localhost traffic in Fiddler


Fiddler is  a great tool to web-debug your HTTP traffic. It acts as proxy between your computer and the Internet. However, by default it does not capture any localhost to localhost HTTP traffic.

I searched on the net regarding this and most of the articles and blogs that I found recommended using a dot “.” (period) after the localhost in your URLs for e.g. use http://localhost.:5282 instead of http://localhost:5282

I tried it but it did not work. The Fiddler’s proxy gave an error for being unable to process this URL. After a couple of more searching I found out that I am supposed to use this URL: http://ipv4.fiddler:5282/ and it worked just fine. J

Happy fiddling.

Tuesday, March 16, 2010

Disabling WCF security


I recently faced an issue from one of our vendors trying to access our web services with their Java clients. They were able to download the WSDL file but got some security errors when calling our web methods. I had tested my web services with my own test clients developed in .NET and they seemed to be working absolutely fine. I decided to investigate this issue and here is what I found:

Whenever you create a new Windows Communication Foundation (WCF) service in Visual Studio.NET 2008, it automatically creates service entries in your application’s configuration file with the default end point binding of wsHttpBinding. I created my sample CustomerService as a WCF service:

<service behaviorConfiguration="WebServiceApp.CustomerServiceBehavior"
    name="WebServiceApp.CustomerService">
    <endpoint address="" binding="wsHttpBinding" contract="WebServiceApp.ICustomerService">
     <identity>
      <dns value="localhost" />
     </identity>
    </endpoint>
   <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>

As you can see the end point binding done is of WSHttpBinding. It uses HTTP transport and by default provides message security along with support for transactions, reliable messaging and WS-Addressing. However the issue is that the default Security mode for WSHttpBinding is Message. The WSHttpSecurity.Message property has its own default behavior of:
I ran Fiddler tool to observe the message exchanges between my .NET test clients and WCF web services. It turned out that the test clients had to call my web service three times (negotiating service credentials, passing the encrypted data and security tokens).

Hence for a proper web service calling to take place the Java clients then should implement this functionality of Message security as required by the WSHttpBinding. After discussions with the vendor it was decided that since the communication takes place over a secure network and the web services being called are not exchanging user credentials (passwords or credit card numbers), I might as well remove the Message security from my web services.

Here is how you can remove disable security:

Removing Message Security by using BasicHttpBinding

Use BasicHttpBinding as the binding for your web service:

<service behaviorConfiguration="WebServiceApp.CustomerServiceBehavior"
         name="WebServiceApp.CustomerService">
  <endpoint address="" binding="basicHttpBinding" contract="WebServiceApp.ICustomerService" />
</service>

For BasicHttpBinding, security is turned off by default.

Removing Message Security from WSHttpBinding

If you want to disable security but at the same time use the WS-Addressing features of WSHttpBinding create a binding entry under bindings->wsHttpBinding and specify Security mode a “None” in your config file:

<bindings>
   <wsHttpBinding>
      <binding name="NoSecurityBinding">
         <security mode="None">
            <transport clientCredentialType="None" />
            <message establishSecurityContext="false" />
         </security>
      </binding>
   </wsHttpBinding>
</bindings>

Then tell your service to use this binding in bindingConfiguration of the end point:

<service behaviorConfiguration="WebServiceApp.CustomerServiceBehavior"
         name="WebServiceApp.CustomerService">
  <endpoint address="" binding="wsHttpBinding" bindingConfiguration="NoSecurityBinding"
            contract="WebServiceApp.ICustomerService" />
</service>


Sunday, March 14, 2010

Test your SOA web services using SOAP UI tool


The SOAP UI tool is a great tool that helps you to quickly test your web services. It is an easy to use tool that makes your SOA testing fun and easy.

I recently had the opportunity to use it on one of my SOA projects and it helped me a lot in debugging my web services. I had published some web services that I had developed in .NET 3.5 using Windows Communication Foundation (WCF) and this vendor company acted as the client consuming those web services. The vendor was developing his client on J2EE technology, possibly JSP/servlets web site.

During testing, the vendor told me that my web services were throwing exceptions containing messages that I had wrapped in a fault contract. The vendor’s development team just sent me the SOAP message that was causing my web service to throw an exception. Here is how I used the SOAP message as an input in the SOAP UI tool  to call my web service method:

Create SOAP UI Project:

Launch your soapUI tool. Right click on the Projects option in the left pane. Select the option of New soapUI Project.


Figure 1

Enter WSDL path:
The new soapUI project menu asks you to enter the name of the project and the WSDL path of your web service. Let’s assume that we will call one of my test web services of ProductsService and will call the web method of CreateProduct. I have published my WSDL at http://localhost:50911/ProductsService.svc?wsdl. I have specified this in Figure 2:


Figure 2

By selecting the check box for Create sample requests for all operations, the tool will automatically generate a sample request SOAP message. Click on OK. The tool generates a sample web request as shown in Figure 3:


Figure 3

Specify the SOAP message:

Double click on Request 1 and you will be able to see the sample request created. I will copy-paste the SOAP message on the Request 1 pane, sent to me from the vendor’s development team:


Figure 4

Note in figure 4 that I have highlighted the node in the SOAP message. The specifies the fully qualified namespace of my service contract of IProductsService’s web method of CreateProduct. The most important thing to note is . Here you will specify the URL path of the test web service where you have hosted. Since I need to debug the web service, I have launched it through Visual Studio.NET:  http://localhost:50911/ProductsService.svc

(I have also added xmlns:wsa="http://www.w3.org/2005/08/addressing" as an attribute of , because apparently soapUI tool does not add this by default).

Here is the SOAP request message:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
                   xmlns:web="http://WebServiceApp.ServiceContracts/"
               xmlns:wsa="http://www.w3.org/2005/08/addressing">
  <soap:Header>
    <wsa:MessageID>urn:uuid:2161b61d-fe07-4cdb-a125-7b221100608awsa:MessageID>
    <wsa:ReplyTo>
    wsa:ReplyTo>
  soap:Header>
  <soap:Body>
    <web:CreateProduct>
      <web:productName>ABCweb:productName>
      <web:productDescription>XYZweb:productDescription>
      <web:productCode>5001web:productCode>
      <web:company>ABCXYZweb:company>
    web:CreateProduct>
  soap:Body>
soap:Envelope>

Call the web service:

Call the web service by pressing on the green play button. As you can see below the web service returns the following fault exception response wrapped in a fault contract:

  <s:Header>
    <a:RelatesTo>urn:uuid:2161b61d-fe07-4cdb-a125-7b221100608aa:RelatesTo>
  s:Header>
  <s:Body>
    <s:Fault>
      <s:Code>
        <s:Value>s:Senders:Value>
      s:Code>
      <s:Reason>
        <s:Text xml:lang="en-US">Product code should be in the range of 1 to 500s:Text>
      s:Reason>
      <s:Detail>
        <DefaultFaultContract xmlns="http://WebServiceApp.FaultContracts/2008/02" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/>
      s:Detail>
    s:Fault>
  s:Body>
s:Envelope>

The vendor has specified the wrong product code. The web service expects the product code to be in the range 1 to 500. After the correcting the SOAP request message I specify product code 400 and consequently get the following successful response message:

  <s:Header>
    <a:RelatesTo>urn:uuid:2161b61d-fe07-4cdb-a125-7b221100608aa:RelatesTo>
  s:Header>
  <s:Body>
    <CreateProductResponse xmlns="http://WebServiceApp.ServiceContracts/">
      <CreateProductResult>25CreateProductResult>
    CreateProductResponse>
  s:Body>
s:Envelope>

Although this example is quite trivial but in case if you have large SOAP request messages having a lot of data fields, then the soapUI tool comes quite handy. 

Saturday, March 13, 2010

Defining ASP.NET MVC routes in web.config

ASP.NET MVC has a very declarative way of defining your routes in the code itself, especially in the Application_Start method of Global.asax.

Since MVC does not have any support of defining them in the configuration file I thought of writing my own configuration section in the web.config and a class that does the simple tasks of mapping the routes and adding simple route constraints. Changes to routes will not require recompilation of your code.

So spending an hour on this I coughed up some code that you can download.

On the other hand, defining routes in code does indeed give the advantage of doing advanced stuff like defining more specific/complex constraints, custom route constraints, ignore routes etc. But if you do not have such requirements and have simple routes you could use this code.

Using the code add the following section under the
of your web.config and add reference to MyWebMvc.dll:

<
section name="mvcroutesgroup" type="MyWebMvc.MvcRoutesConfiguration, MyWebMvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=nullallowLocation="true" allowDefinition="Everywhere"/>

Then declare your routes such as:

<mvcroutesgroup>
  <mvcroutes>



    <route name="Product" url="Product/{action}/{id}">
      <controller name="Product" />
      <constraints>
         <constraint key="id" value="\d+" />
      </constraints>
    </route>
  <route name="Default" url="{controller}/{action}/{id}">      <controller name="Home" action="Index" id="" />
    </route>
  </mvcroutes>
</mvcroutesgroup>

Add the following code where you register your routes in the Global.asax file:

MvcRoutes.Initialize(routes);

What I can add later here is the support for:


  • Namespaces (to be used in Areas)
  • Ignore routes
You can download the code from here.