ASP.NET ScriptService反序列化问题,派生类型
-
26-09-2019 - |
题
我有一个ScriptService
幅方法(.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
对象Group
。我打电话从jQuery的这种服务;我没有使用微软的客户端框架。调用其它方法工作良好。
的问题::当我打这个电话,一个异常甚至调用我的方法前抛出。例如,如果我的呼叫是:
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
(和从abstract
除去Item
改性剂),异常消失了,但是所得到的反序列化对象显然有点无用。
我缺少什么?
解决方案
啊哈!点击围绕在这个问题上的右侧的相关链接,我发现的答案,帮助我解决这个问题。
在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) { ... }
}
如果没有这些属性,解串器不知道我的派生类型
其他提示
我可以解决这个使用Newtonsofts JsonConvert
如下。
[System.Web.Services.WebMethod]
public static void MyAjaxCallingMethod(object inputs)
{
string stingDataFromAjaxCall = JsonConvert.SerializeObject(inputs);
MyObject myObj = JsonConvert.DeserializeObject<MyObject>(stingDataFromAjaxCall);
....}
不隶属于 StackOverflow