【问题标题】:ASP.NET ScriptService deserialization problem with derived types派生类型的 ASP.NET ScriptService 反序列化问题
【发布时间】:2011-04-18 15:47:50
【问题描述】:

我有一个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 客户端框架。调用其他方法可以正常工作。

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

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 修饰符),异常就会消失,但生成的反序列化对象显然有点没用.

我错过了什么?

【问题讨论】:

  • 我遇到了这样的错误,但我的问题完全不同。我将 WCF 服务转换为 ASMX 服务。每个人都对__type 属性使用不同的格式。更新 __type 以使用 ASMX 的格式完全解决了我的问题。

标签: c# javascript ajax json scriptservice


【解决方案1】:

啊哈!点击这个问题右侧的相关链接,我发现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】:

    我可以使用Newtonsofts JsonConvert 解决这个问题,如下所示。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-22
      • 1970-01-01
      • 2012-05-25
      • 2017-09-03
      • 2013-07-11
      • 2012-09-20
      相关资源
      最近更新 更多