代码之家  ›  专栏  ›  技术社区  ›  josh3736

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

  •  7
  • josh3736  · 技术社区  · 14 年前

    我有一个 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 将是一个 Group 其中包含 Instance 物体。我从jQuery调用此服务;我没有使用Microsoft客户端框架。对其他方法的调用工作正常。

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

    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"}
    

    __type JSON对象的成员或将其更改为 Namespace.Item abstract 修改器来自 Item ),异常会消失,但得到的反序列化对象显然有点无用。

    我错过了什么?

    2 回复  |  直到 14 年前
        1
  •  15
  •   Community CDub    7 年前

    啊哈!点击这个问题右侧的相关链接,我发现 an answer 帮助我解决了这个问题。

    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) { ... }
    }
    

        2
  •  0
  •   Suraj Rao Raas Masood    6 年前

    我可以用 Newtonsofts JsonConvert 如下所示。

    [System.Web.Services.WebMethod]      
    public static void MyAjaxCallingMethod(object inputs)
        {           
        string stingDataFromAjaxCall = JsonConvert.SerializeObject(inputs);
                MyObject myObj = JsonConvert.DeserializeObject<MyObject>(stingDataFromAjaxCall);
                ....}