ASP.NET ScriptService与派生类型的反序列化问题

我有一个ScriptService Web方法(.NET 3.5),它接受一个抽象基类型的单个参数:

 [WebMethod(EnableSession=true)] [ScriptMethod()] public bool Test(Item item) { ... } 

和:

 namespace Namespace { public abstract class Item { public int id; } public class Group : Item { public Item[] items; } public class Instance : Item { public string whatever; } } 

通常,在调用方法时, item将是包含Instance和/或Group对象的Group 。 我从jQuery调用这个服务; 我没有使用Microsoft客户端框架。 调用其他方法工作正常。

问题:当我进行调用时,在我的方法被调用之前会抛出exception。 例如,如果我的电话是:

 POST /WebService.asmx/Test HTTP/1.1 Content-Type: application/json; charset=UTF-8 Accept: application/json, text/javascript, */* {"item":{"id":0,"__type":"Namespace.Group","items":[]}} 

…我得到一个InvalidOperationException

 {"Message":"Operation is not valid due to the current state of the object.","StackTrace":" at System.Web.Script.Serialization.ObjectConverter.ConvertDictionaryToObject(IDictionary`2 dictionary, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)\r\n at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeInternal(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)\r\n at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeMain(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)\r\n at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)\r\n at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeDictionary(Int32 depth)\r\n at System.Web.Script.Serialization.JavaScriptObjectDeserializer.DeserializeInternal(Int32 depth)\r\n at System.Web.Script.Serialization.JavaScriptObjectDeserializer.BasicDeserialize(String input, Int32 depthLimit, JavaScriptSerializer serializer)\r\n at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize(JavaScriptSerializer serializer, String input, Type type, Int32 depthLimit)\r\n at System.Web.Script.Serialization.JavaScriptSerializer.Deserialize[T](String input)\r\n at System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)","ExceptionType":"System.InvalidOperationException"} 

如果我删除JSON对象的__type成员或将其更改为Namespace.Item (并从Item删除abstract修饰符),则exception消失,但生成的反序列化对象显然有点无用。

我错过了什么?

啊哈! 点击这个问题右侧的相关链接,我找到了一个帮助我解决这个问题的答案 。

必须将GenerateScriptType属性应用于Web服务类:

 [WebService( ... )] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ScriptService] [GenerateScriptType(typeof(Group))] [GenerateScriptType(typeof(Instance))] public class WebService : System.Web.Services.WebService { [WebMethod(EnableSession=true)] [ScriptMethod()] public bool Test(Item item) { ... } } 

没有这些属性,反序列化器不知道我的派生类型。