JSON serialization and “Error invoking service.”

To serve up my menu XML files which I already have .NET serialization classes for, I’ve created a webservice:

[WebService(Namespace = "http://www.simonransom.com/menuservice/3.0")]

[

WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

[

ToolboxItem(false)]

[System.Web.Script.Services.

ScriptService]

public class MenuService : System.Web.Services.WebService

{

    [

WebMethod]

    [

ScriptMethod(ResponseFormat = ResponseFormat.Json)]

    public SegmentedMenu Load(string menu)

    {

        string path = Server.MapPath("~/menufiles/" + menu);

        return new SegmentedMenu(MenuManager.GetInstance().Load(path));

    }

}

From this I learnt a few things:

  • If I went to the webservice page menuService.asmx in Internet Explorer or Firefox, the browser would only return the XML version of the results which looked fine (as long as you were expecting XML – which given that I’d specified Json serialization I wasn’t)
  • Using TCPTrace from Simon Fell & Matt Humphrey, the message requests from Silverlight were of the more expected form and have a MIME Content-Type of application/json

     {"menu":"publicphotos.xml"}

  • So it looks like .NET is supporting both serialization forms depending on the client request type. The response back to Silverlight from my webservice is in the form:

{"d":{"__type":"PBL.App.Menus.WebService.SegmentedMenu","Header":{"MenuLargeImage":null,"Filename":"publicphotos.xml","AudioPlaylist":null,"A… etc.

  • For some of the menus I get a System.Net.WebException with a message stating "Error invoking service." (not particularly helpful and no inner exception). However in TCPTrace I get a more helpful:

     {"Message":"Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property.","StackTrace":"   at System.Web.Script.Services.RestHandler.InvokeMethod(HttpContext context, WebServiceMethodData methodData, IDictionary`2 rawParams)rn   at System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)","ExceptionType":"System.InvalidOperationException"}

  • My original menu serialization used inheritance and System.Xml.Serialization.XmlInclude to have a base MenuItem and subclasses of MenuItemPhoto, MenuItemMovie, etc. however although the XML looked ok, the JSON serialization format does not support OO inheritance so all the classes on the client end were stripped down to the base class MenuItem. To work around this, I created a SegmentedMenu class which could be created based on the original Menu class but separated each of the MenuItems into different lists (e.g. List<MenuItemPhoto> photos) depending on class type. This could then be passed back but loses the benefit of interleaving different types and increases a mapping overhead but overall not a bad solution for what I need.

So now I need to work out how make the larger menus smaller or increase the maxJasonLength property.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s