Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

Serializing to client script

I finally subscribed to Rick Strahl’s blog because an inordinate number of my Googling ends up there. It’s a little freakish the number of times I’ve hit his blog and had it solve the exact obscure problem I’m having.

After subscribing and going through some recent posts, I stumbled on his very own Ajax Toolkit. Having had my fill of Ajax libraries of late, I scanned through it and noted it for later reference, paying particular attention to the JSON Serializer, a problem I was trying to tackle at the time. But again, I was kind of averse to frameworks so I moved on.

Fast forward a few hours. I had been fighting with some client-side stuff dealing with a collection of items that I had planned to magically get from the server in JSON form and the time had come to actually implement that. The first attempt was courtesy of Scott Guthrie who outlined how to do it pretty specifically. At the end, he mentions the DataContractJsonSerializer class as a replacement for JavaScriptSerializer and I go about implementing it. Didn’t get too far but wouldn’t you know it, a Google for implementing DataContractJsonSerializer brings up Rick’s blog on the first page and gosh darn if his explanation succeeded where others failed.

But immediately, things start to look funny with the use of DataContractJsonSerializer. All of a sudden I have to start decorating all my domain objects with [DataContract] and [DataMember] attributes. But I started down the path because if I could justify adding attributes for that, it’s not so hard to extend the argument to use ActiveRecord which I kind of got excited about because it would make things go that much faster.

So I cut and pasted [DataMember]s until the bovines migrated to the abode and eventually got the sucker writing out a JSON string for my collection as advertised. Then I added an NHibernate mapping to the class…

Until then, I had been playing with everything on the client only and I was dealing with an empty and unpersisted collection of objects. Now it was time to start dealing with persistence so the NHibernate mapping had to be done. It was then that I ran into the problem outlined here. Namely, even when you make the relevant NHibernate types known to the serializer, it still has problems deserializing using DataContractJsonSerializer. And even if it didn’t, even someone as loose with attributes as I am has trouble justifying a reference to NHibernate from my domain project strictly so that the sucker can be converted into a string.

At that point, I recalled Rick’s West Wind Ajax Toolkit and the JSON Serializer within. And I’m happy to report that it works smashingly. No [DataContract] and [DataMember] attributes. No references to NHibernate from my domain. No workarounds to serialize NHibernate classes. It just plain works. So far at least. Though I’ll admit that I had to turn off lazy loading on my object to make it work. A compromise I’m willing to live with for the moment because the collection I’m serializing consists of value objects so there’s not much chance of getting too deep into the hierarchy.

And the jury’s still out on whether JSON is an easier format to deal with. Yes, it has advantages when dealing with it in client code. But the number of hoops I’m jumping through to get it into that format had better be worth it.

Kyle the Circus Lion

This entry was posted in Javascript. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Nuno Santos

    Hi,

    I’m having problems serializing an LLBL entity to Json.

    Did you get it Bryan?

  • Kyle Baley

    Good points all. I didn’t consider looking at this as a “traditional” service boundary serialization issue. After all, I’m not passing objects back and forth ‘twixt web services. I’m basically just trying to get < %=job.Locations.ToJson( ) %> to work. But as a couple of you have mentioned, a DTO is one common way to guard against this.

    One of the reasons this didn’t occur to me is that the interface for my object doesn’t make any mention of NHibernate. It contains a generic IList of Location objects and when it gets created, NHibernate uses its own type to create that list (I’d hazard a guess as to which type it actually was but chances are Ayende’s NHibernate senses are tingling already and he’ll probably just end up correcting me anyway. Oh, all right, I think it’s NHibernate.Collection.Bag). I guess I had assumed it would create a plain old generic List.

    Looking through Rick’s code for the Serializer, it looks like it’s working because it treats the object as a DTO rather than some special .NET thing that can be serialized through some internal mechanism.

    So there you have it. Someone comes asking why you need to convert your objects into another format that is almost exactly like the original, you can point them here and explain the nature of “almost”.

  • Ian Cooper

    I have to agree with the notion that using a DTO is preferable to serializing your domain objects over the wire. Firstly, you want to share schema not type, because you should not be making assumptions about your client. Second you are expressing a contract with the consumer and you do not necessarily want to force your consumer to change every time you want to make a refactoring in your domain. DTOs provide a nice insulating layer here for you. They also let you flatten out your model.

  • http://blog.symbiotic-development.com Symon Rottem

    That’s my experience too. Ideally you should try to avoid transferring any objects persisted in NHibernate across service boundaries – there are too many gotchas.

    Serialization for transfer between systems can only ever really deal with lightweight objects…think web services where your object from .NET needs to be transferred to a client running Delphi 7 or PHP; you can’t transfer those .NET language specific semantics so you’re better off constructing simple DTOs that have simple arrays (or types that can generate arrays such as generic collections as mentioned in the article you referenced) to serialize and send over the wire.

  • John Doe

    That’s one reason why DTO’s are good. It doesn’t impact your project’s architecture based on data representation needs.

  • http://Bryan.ReynoldsLive.com Bryan Reynolds

    Thanks for the summary of your fight for JSON serialization. I will be heading down this path soon with LLBLGen entities. Wish me luck!

    Bryan