Monday, December 26, 2011

Creating and exposing simple REST based services in WCF 4.0

ReST (Representational State Transfer) is something which makes the web service url easy to remember by pointing a resource rather than a web page.ie it done have the page.aspx and the query string syntax. For example consider the scenario where I need to get the details of employee named “Joy”

Traditional way : www.company.com/Employee.aspx?name=Joy
ReST way : www.company.com/employees/Joy

There is not question that the Rest URL is simple. Now lets look at how to create such a service in .Net 4.0.
  • Create a web application normally.
  • Add a WCF service to the project.
  • Right click on the .svc file and view markup . Add Factory="System.ServiceModel.Activation.WebServiceHostFactory into the <%@ ServiceHost node.
  • In the Service interface methods add [WebGet] attribute. This makes them visible to the ReST service. Set the URI template of the WebGet properly.
So above are the steps to follow. Lets now see one example Service contract.Famous DoWork method to ReST.
[ServiceContract]
public interface IMyService
{
        [OperationContract]
        [WebGet]
        string DoWork ();
}
The implementation is same.No change .
public class MyService : IMyService
{
    public string DoWork ()
    {
        return "Yes.Our ReST service worked!!!";
    }
}

All set.Hit F5 and in the browser type http://localhost:<port>/myservice.svc/dowork .You can see the output as xml.
<?xml version="1.0"?>
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Yes.Our ReST service worked!!!</string>


WCF ReST return as JSON

Its little difficult for the calling party to process the xml and one more issue is the xml is heavy.So the immediate solution which comes to this scenario is the JSON format. Its easy to make our output to JSON.Just change the WebGet to specify JSON format as follows.

[WebGet(ResponseFormat=WebMessageFormat.Json)]


How to pass parameters to the WCF ReST services

Nobody is going to have only simple services as above in any of the projects. Passing arguments are necessary in WCF ReST services and its supports too using the UriTemplate property of WebGet.

[OperationContract]
[WebGet(UriTemplate="/Add/{a}/{b}")]
int Add ( string a, string b );
Implementation as follows.
public int Add(string a, string b)
{
    int num1, num2;
    if (int.TryParse(a, out num1) && int.TryParse(b, out num2))
    {
        return num1 + num2;
    }
    throw new ArgumentException("Give numbers to add");
}

Look at the UriTemplate it tells how the arguments are going to arrive. So call the service appropriately.


Points to Note

The steps which I performed are very basic and this is working since the framework is 4.0 where it automatically use the WebHttpBinding and other configurations. If you are using old frameworks you may need to set the binding properly.

Another thing is the parameters here are string. So convert them accordingly. I don't thing a sample is needed to see this in your computer.

There are more scenarios in this like such as how to pass and return complex types and how to use the Http Post etc...Hope I can post later.

Monday, December 5, 2011

Successfully tried Windows Azure AppFabric Caching in Azure environment

You might have wondered why I am telling this as an achievement. It is meant to cache the data and what is there to say "Successfully tried". Yes.There are so many things to say about it even though there are so many articles which explain how to cache in a step by step manner with images. Roughly speaking it took me 3 days to test the caching in the real Azure hosted environment. Below are the issues we faced during the process.

Issue 1 : Wrong SDK version ie Azure SDK to Azure Guest OS mapping


Initially I was using Azure SDK 1.6 which is not supported in the Azure production servers. More details are explained here. Most of the time we were getting the DataCacheException with ErrorCode<ERRCA0017> which is nothing but RetryLater. Funny part is when we reverted to SDK 1.5 retry disappeared.

Issue 2 : Windows AppFabric v/s Azure AppFabric


Azure emulator don't have support to simulate Azure caching. So the idea was to use the Windows AppFabric cache which can be installed in our local machines and later change the configuration to use the actual Azure AppFabric .After configuring Windows AppFabric using Windows PowerShell and all we were able to connect to the local cache .But after hosting the same code to Azure, we came to know that there are some differences between Windows Server AppFabric and the Azure AppFabric. It made us rewrite our AppFabricCacheProvider class based on the Azure AppFabric caching API reference. The exceptions we got at this stage was NotSupportedException.
Below are some links which explains how to setup Windows Server AppFabric caching.
http://msdn.microsoft.com/en-us/library/ff637746.aspx
http://www.wadewegner.com/2010/08/getting-started-with-windows-server-appfabric-cache/

Issue 3 : Network issues to access caching clusters in your development environment


We tried to access the real Azure AppFabric cache from out development environment. The Azure caching machine was not reachable from our normal company network. My be some firewalls were in middle. We had resolved it using another external internet connection which don't have any restriction.
If you happen to face this issue, you will get exception which says it cannot access some particular IPAddress which you can easily verify by pinging or tracert

Issue 4 : AppFabric dlls to be included in the Azure publish package.


After 2 days we were able to successfully implement the caching framework and access Azure AppFabric cache from services in our development environment.Everybody became happy for some moment .But we lost the mood when we hosted our services in the Azure. Since we haven't implemented any logging framework it was really difficult for us to get the exact exception. The exception was mainly happening on the line .


DataCacheFactoryConfiguration = new DataCacheFactoryConfiguration("clientName");


Finally we were able to track that down to assembly not found issues ie "The system cannot find the file specified. Could not load file or assembly 'Microsoft.WindowsFabric.Common, Version=1.0.0.0" . Yes we were missing some dlls in the package which we uploaded to Azure. It was from the C:\Program Files\Windows Azure AppFabric SDK\V1.5\Assemblies\NET4.0\Cache folder.We added all the dlls, present in this location to our package and it stated working. Better refer these dlls in your web project / service host project so that these will be packaged automatically.

Microsoft.Web.DistributedCache.dll
Microsoft.WindowsFabric.Common.dll
Microsoft.WindowsFabric.Data.Common.dll

The question remains ,how it worked in the emulator? Answer was simple. All these dlls were in our GAC. in Azure machines, GAC don't have these dlls.

There were so many minor issues like the letter casing of <dataCacheClients>,should we use the <dataCacheClients> or <dataCacheClient> section in the config, port 22233 was blocked etc...Below are some links if you are struggling to get Azure AppFabric Caching working

http://blog.bareweb.eu/2011/07/hello-world-with-azure-appfabric-caching-service-v1-0/
Exercise 3: Creating a Reusable and Extensible Caching Layer
Appendix 1: Table of Error Code Strings