views:

323

answers:

2

I'm currently enabling JSON calls to my web services using the ScriptService attribute. The problem is that one of my classes references a second class and .Net is not picking up and writing out the JavaScript for the second class.

As a workaround I can write a dummy method that just returns the second class. Then .Net writes the JSON to allow it to be serialized. So in the following example:

[ScriptService]
public class MyService : WebService {
    [WebMethod]
    public void SaveClass1(Class1 class1) {
        ...
    }
}

[Serializable]
public class Class1 {
    public Class2 class2 { get; set; }
}

[Serializable]
public class Class2 {
}

MyService.asmx/js won't write code to allow me to instantiate Class2 in order for me to populate Class1. But I can make it work if I add:

[WebMethod]
public Class2 Dummy() {
    return new Class2();
}

to MyService. Any alternatives to my nasty workaround would be greatly appreciated.

A: 

Lee, not sure if this works in your JSON/[ScriptService] scenario, but to serialize an object graph in Searcharoo.net I used the System.Xml.Serialization.XmlInclude attribute on the 'base' class that I needed to serialize.

Basically this tells the XmlSerializer about Class2 so that it can be included in the Class1 serialization... kinda like an "opt-in" strategy for handling deep hierachies of objects.

You would add it like this (in your example):

[Serializable]
[System.Xml.Serialization.XmlInclude(typeof(Class2))]
public class Class1 {
    public Class2 class2 { get; set; }
}

...and then this

[WebMethod]
public void SaveClass1(Class1 class1) {
    ...
}

should return JSON with Class2 data inside Class1.

I did a quick google to find troubleshooting...XmlSerializer which might be a good read. HTH

CraigD
XmlInclude is used to include derived types in WSDL service descriptions. In this question, Class2 is not derived from Class1 and the server generates JavaScript code not a WSDL service description. Use GenerateScriptTypeAttribute instead.
Daniel Richardson
+3  A: 

You need to use System.Web.Script.Services.GenerateScriptTypeAttribute, which specifies that a server type should be included in the generated proxy code. You can apply this attribute to the web service itself or any method marked with WebMethodAttribute.

For example:

[ScriptService]
[GenerateScriptType(typeof(Class2))]
public class MyService : WebService {
    [WebMethod]
    public void SaveClass1(Class1 class1) {
        // ...
    }
}
Daniel Richardson