Wednesday, March 13, 2013

Lest we forget, WCF is Windows Communication Foundation, not Web Communication Foundation. nod nod wink wink

Suffice to say, WCF was not created with web app in mind, try to interoperate WCF with a web front-end, I think (sorry I didn't do my homework) it's doable, but I would hazard a guess that a web-facing API fashioned out of WCF service will feel very byzantine, e.g. what is the DataMember attribute's business to a jQuery-driven or AngularJS-driven web app?



Yesterday, we have encountered a WCF limitation where we cannot transport a dictionary object from WCF to ASP.NET MVC, then from MVC we need to transport the dictionary object as JSON object. We are using ASP.NET MVC controller as a service for delivering JSON to a web front-end that needed the data, as ASP.NET MVC has a more natural affinity to web and JSON than a WCF to web and JSON is.



In a nutshell, every web application is really just one complex marshaling problem, we marshal the data from DB through WCF, then through ASP.NET MVC, then through JSON, then to the DOM, and then we do it all again in reverse order. If only the first gateway(e.g. WCF) can marshal (via JSON) our data directly to a web front-end, we won't even need ASP.NET MVC to carry out the last step, we can just directly return JSON data right there on the first gateway. Today we will explore that option, albeit without WCF nor ASP.NET MVC.





Here's the summary of steps

1. Create a web server. We can use anything here, for simplicity sake we will just use ASP.NET Web application

2. Create a ServiceStack. We replace both WCF and ASP.NET MVC JSON server with ServiceStack

3. From the web front-end(jQuery or AngularJS) use the JSON from ServiceStack

4. Profit!





Step 1. Create a new ASP.NET Web Application

Step 2. Get the "Starter ASP.NET Website Template - ServiceStack at /" from NuGet



Edit WebServiceExample.cs to this:

public Person Any(Hello request)
{
    return new Person { Lastname = "Torvalds", Firstname = "Linus", Age = 42 };
}


Note that you don't even need to explicitly serialize the object to Json on the service, here's a sample output via this url: http://localhost:62015/hello?format=json



Note that the above code and all the code that follows have this output:

{"Lastname":"Torvalds","Firstname":"Linus","Age":42}

You can even specify object as the returned type, and everything still works as expected:

public object Any(Hello request)
{
    return new Person { Lastname = "Torvalds", Firstname = "Linus", Age = 42 };
}


So what's the implication of being able to return just an object type? we can use anonymous type!

public object Any(Hello request)
{
    return new {Lastname = "Torvalds", Firstname = "Linus", Age = 43};
}


How about the humble dictionary that WCF is refusing to marshal? It Just Works on ServiceStack

public object Any(Hello request)
{            
    var d = new Dictionary<string, object>();
    d.Add("Lastname", "Torvalds");
    d.Add("Firstname", "Linus");
    d.Add("Age", 44);
    return d;
}


How about the dynamic object we originally intended to use on WCF which WCF is not capable of marshalling? Keep them coming, It Just Works on ServiceStack!

public object Any(Hello request)
{
        dynamic person = new System.Dynamic.ExpandoObject();
 
        person.Lastname = "Torvalds";
        person.Firstname = "Linus";
        person.Age = 45;
 
        return person;
}


And the kind of marshalling dynamic data we originally (dictionary is just a plan B, which doesn't work on WCF) intend to do on WCF which WCF is not capable of? Marshalling dynamic is perfectly fine on ServiceStack. FTW!

public object Any(Hello request)
{
        dynamic person = new System.Dynamic.ExpandoObject();
 
        person.Lastname = "Torvalds";
        person.Firstname = "Linus";
        person.Age = 46;
 
        var dictPerson = (IDictionary<string, object>)person;
 
        var r = new Random();
        for (char c = 'A'; c <= 'E'; c++)
        {
               dictPerson[c.ToString()] = r.Next(7);
        }
 
        return person;
}


Sample output:

{"Lastname":"Torvalds","Firstname":"Linus","Age":46,"A":5,"B":6,"C":2,"D":3,"E":5}


Step 3. From the web front-end(jQuery or AngularJS) use the JSON from ServiceStack. Left as an exercise to the reader

Step 4. Profit! Left as an exercise to the reader


ServiceStack is the best SOA framework your web front-end can communicate to


That's it folks, everything just works the way we intend things to!


Happy Coding! ツ


No comments:

Post a Comment