7

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を含むになります。このサービスをjQueryから呼び出しています。Microsoftのクライアント側フレームワークを使用していません。他のメソッドの呼び出しは正常に機能します。InstanceGroup

問題: 呼び出しを行うと、メソッドが呼び出される前に例外がスローされます。たとえば、私の呼び出しが次の場合:

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

__typeJSONオブジェクトのメンバーを削除するか、に変更するとNamespace.Item(そして、abstractから修飾子を削除するとItem)、例外はなくなりますが、結果として得られる逆シリアル化されたオブジェクトは明らかに役に立たないものです。

私は何が欠けていますか?

4

2 に答える 2

15

あはは!この質問の右側にある関連リンクをクリックすると、この問題の解決に役立つ回答が見つかりました。

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

これらの属性がないと、デシリアライザーは派生型を認識できません。

于 2010-09-29T06:20:55.257 に答える