2010-09-29 25 views
6

Tôi có một phương pháp ScriptService web (.NET 3.5) mà phải mất một tham số duy nhất của một loại cơ sở trừu tượng:vấn đề deserialization ASP.NET ScriptService với các loại có nguồn gốc

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

Và:

namespace Namespace { 
public abstract class Item 
{ 
    public int id; 
} 

public class Group : Item 
{ 
    public Item[] items; 
} 

public class Instance : Item 
{ 
    public string whatever; 
} 
} 

Thông thường, khi phương thức được gọi, item sẽ là Group có chứa các đối tượng Instance và/hoặc Group. Tôi đang gọi dịch vụ này từ jQuery; Tôi không sử dụng khung công tác phía máy khách của Microsoft. Các cuộc gọi đến các phương thức khác hoạt động tốt.

Sự cố: Khi tôi thực hiện cuộc gọi, ngoại lệ được ném trước khi phương thức của tôi được gọi ngay cả. Ví dụ, nếu cuộc gọi của tôi là:

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":[]}} 

... tôi nhận được một 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"} 

Nếu tôi thả __type thành viên của đối tượng JSON hoặc thay đổi nó để Namespace.Item (và loại bỏ các abstract sửa đổi từ Item), ngoại lệ biến mất, nhưng đối tượng deserialized kết quả rõ ràng là kinda vô ích.

Tôi đang thiếu gì?

+0

Tôi gặp lỗi như thế này nhưng vấn đề của tôi hoàn toàn khác. Tôi đã chuyển đổi một dịch vụ WCF thành một dịch vụ ASMX. Mỗi cái sử dụng một định dạng khác cho thuộc tính '__type'. Việc cập nhật '__type' để sử dụng định dạng của ASMX đã giải quyết xong vấn đề cho tôi. – sparebytes

Trả lời

14

Ah ha! Nhấp vào các liên kết có liên quan ở phía bên phải của câu hỏi này, tôi đã tìm thấy an answer đã giúp tôi giải quyết vấn đề này.

Các GenerateScriptType thuộc tính phải được áp dụng cho các lớp dịch vụ 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) { ... } 
} 

Nếu không có những thuộc tính, các deserializer không biết về các loại có nguồn gốc của tôi.

Các vấn đề liên quan