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