So I’m finally getting an opportunity to work with Silverlight in a real application. I had mentioned this application in the past a few weeks back – the original application architecture was created as a Flash front end to a .NET backend which provides service style XML data. In the original app the server infrastructure was used purely to serve data to the client – basically a complex, mostly meta data drive SQL Engine based on complex stored procedures feed the client Xml data. Originally our data format has been DataSets because those were the easiest way to consume the data in the Flash client since there’s native support for DataSets and it greatly facilitated the process of passing data to flash and the format is basic enough that it’s easy to send update data back from the client (manually created in this case).
In the original app I basically built the data engine – which is a custom HttpHandler based affair that basically is a glorified XML routing engine that maps inbound requests from the client who sends XML data to the appropriate business object/Stored Procedure routine which in turn responds with a data result that is streamed back to the client. The server app and business objects actually do very little work in this process – most of the work lives in the SQL backend with its stored procedures that manipulate the data. The business object’s tasks mostly is to pick up inbound query parameters and map those into the appropriate stored procedure calls. The results for now are returned were returned as DataSets and there’s a bunch of extra logic that can also return that same data out as either JSON or as simplified XML (without DS schemas).
This has all worked well, but it’s been based on the existing Flash expertise at the time, which have now become an issue.
So based on some back and forth discussions the thinking now is that since we’re starting from scratch Silverlight is probably a better choice due to the easier coding model and readily available developer pool. Which has landed me smack in the middle of Silverlight and not least of all a data access decision to make. :-}
Data Models
The main issue I’m working on at the moment is finding the right data model. The server side as it sits right now has a number of options for returning data to the client. Silverlight has many options for getting data to the client:
Raw Xml
Obviously we can retrieve the raw XML from the server and just parse that on the fly. While not difficult this would not be my choice for data access because it’s tedious and potentially error prone. Since the data is mostly dynamic and doesn’t lend itself to mapping well though this is not totally unreasonable because we’ll likely end up with some sort of untyped data representation on the client no matter what.
JSON or ADO.NET Data Services
As I mentioned our backend can actually feed data out as JSON so another option I was toying with is to use JSON marshalling to map onto objects. The problem with this approach is that we don’t really have a model we can map to. The problem is that the backend (over which I have no control at this point) is just a fairly large set of heavily parameterized stored procedures. While the actual simple tables in the system are fairly small and could be modelled, the way the data is manipulated and returned does not lend itself well to producing either a Linq to SQL or Entity Framework data model. We’d end up with about a hundred or more hand created types that would have to be kept in synch with the database. That doesn’t sound very promising either.
ADO.NET Data Services could be interesting for certain data scenarios, especially free form data access, but my current scenario isn’t one of them I think. Still digging through the docs on ADS but I think when dealing with stored procs there’s really nothing here to help effectively. Nor is the structure of this architecture really a good fit. To make this work would be square peg, round hole.
Web Services
Web Services provide another possible option. Silverlight can directly access WCF Web services and retrieve data that way and this is actually a pretty easy interface to work with. But again it requires fixed, typed result sets so the issues are somewhat similar as the previous item. You need to be able to full type information published on the server in order to get the data back to the client.
One thing I was thinking about was to return a result back from a Web Service as a generic dictionary which actually serializes properly, preserving underlying type information:
[OperationContract]
public Dictionary<string, object> GetDictionary()
{
Dictionary<string, object> items = new Dictionary<string, object>();
items.Add("Field1", 10);
items.Add("Field2", DateTime.Now);
items.Add("Field3", "Rick");
return items;
}
Properly returns in Silverlight as:
private void btnService_Click(object sender, RoutedEventArgs e)
{
PraServiceClient service = this.GetService();
service.GetDictionaryCompleted +=
new EventHandler<GetDictionaryCompletedEventArgs>(service_GetDictionaryCompleted);
service.GetDictionaryAsync();
}
void service_GetDictionaryCompleted(object sender, GetDictionaryCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show( e.Error.Message, "Service Error",MessageBoxButton.OK);
return;
}
Dictionary<string, object> items = e.Result;
StringBuilder sb = new StringBuilder();
sb.Append(items["Field1"]);
sb.Append(items["Field2"] + items["Field2"].GetType().ToString()) ;
sb.Append(items["Field3"] + items["Field3"].GetType().ToString());
MessageBox.Show(sb.ToString());
}
private PraServiceClient GetService()
{
EndpointAddress addr = new EndpointAddress("http://rasnote/PraWebService/PraService.svc");
BasicHttpBinding bind = new BasicHttpBinding();
return new PraServiceClient(bind, addr);
}
The above surpringly works to marshal types in the dictionary down to the client even though the dictionary is Dictionary<string,object>. WCF does not like serializing generic object types however so results of type object or anonymous types fail outright. I suspect using these types as values for the dictionary too will fail.
Dynamic Data Access
The real issue here is that in lieu of a data model that can be used on the client side there’s no good data mechanism built into Silverlight that provides access to some dynamic data returned from the server. So say the server returns an arbitrary query where the user is allowed to pick the columns he wants to retrieve there’s really no clean way to return that data and present it on the client side. JSON serialization requires a type as an input to understand the structure and so a dynamic results can’t be represented. It’s possible to actually use JavaScript to create an object but even then that object comes back as a dynamic object which could only be accessed by Reflection (C# 4.0 dynamic oh where are you? <s>)
No DataSet Support
I know DataSets are kind of passé but when I really think about how this existing data engine works – DataSets with their weak typing and even with their update support are the perfect fit for this type of application. As many problems as DataSets have in typical pure data access scenarios, in internally controls disconnected scenarios Datasets have features that none of the newer data techologies have matched to date – mainly because DataSets allow for dynamic data to be returned and be accessed easily.
Alas – Silverlight has no support for DataSet/DataTable/DataRow. While looking at various third party components I actually ran into ComponentOne’s Silverlight Controls which include a Data assembly that provides a minimal set of the classic ADO.NET objects for Silverlight. But even with those the support is fairly limited (for example no support for schemaless XML or Diffgrams – the latter of which is kind of a bummer). Still for now that’s something to start with – if we decide to go this route I suppose it’s not terribly difficult to build my own abstraction that does support this functionality.
Something Custom?
I’ve also toyed with the idea of building a custom Dictionary type interface that I can deserialize from JSON which would basically allow me to use JSON from the server and get some sort of generic object back back on the client. Since the data is for the most part table based, object hierarchy isn’t really an issue either so it’d be fairly straight forward to build up something like this fairly easily.
Yes, C# 4.0 and DynamicObject would be pretty handy for this, but it’s going to be some time before that comes to pass.
Hmmm…
In some ways these issues are actually easier to work through in JavaScript/Html based interfaces. Because Javascript is a dynamic language it’s actually easier to retrieve JSON data from the server and use it on the client. The server can return arbitrary data and simply return it with the client having direct access to it. I suppose one could choose one of the dynamic languages (JavaScript, IronPython or IronRuby) on the client, but frankly that’s not really a good option either. The whole point of using Silverlight is to provide the richer, statically typed environment.
So I’m curious to hear what others are doing for their client side ‘data’ connectivity, especially when dealing with data that can’t be easily serialized back and forth between client and server. I suspect a lot of folks probably deal with raw data – manually parsed XML or possibly. If not what are you doing for data transfers? There are a many options but it seems that most of them have some shortcomings when it comes to effectively dealing with the data on both ends of the connection.
Other Posts you might also like