Frage

Ich habe eine ScriptService Web-Methode (.NET 3.5), die einen einzelnen Parameter einer abstrakten Basistyp nimmt:

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

Und:

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

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

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

Normalerweise, wenn die Methode aufgerufen wird, wird item ein Group sein, die Instance und / oder Group Objekte enthält. Ich rufe diesen Service von jQuery; Ich bin nicht mit dem Microsoft-Client-Seite Rahmen. Anrufe zu anderen Methoden funktionieren.

Das Problem: Wenn ich den Anruf zu tätigen, wird eine Ausnahme ausgelöst, bevor meine Methode auch aufgerufen wird. Zum Beispiel, wenn mein Aufruf:

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

... ich eine InvalidOperationException bekommen:

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

Wenn ich das __type Mitglied des JSON-Objekt fallen und vermeiden Sie Namespace.Item ändern (und entfernen Sie den abstract Modifikator von Item), die Ausnahme geht weg, aber die resultierende deserialisiert Objekt ist offensichtlich irgendwie nutzlos.

Was bin ich?

War es hilfreich?

Lösung

Ah ha! Durch Anklicken um die entsprechenden Links auf der rechten Seite dieser Frage fand ich eine Antwort , die mir geholfen, dieses Problem zu lösen.

Das GenerateScriptType Attribut muss auf die Web-Service-Klasse angewandt werden:

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

Ohne diese Attribute, wird der Deserializer nicht über meine abgeleiteten Typen kennen.

Andere Tipps

Ich kann dies mit Newtonsofts JsonConvert lösen, wie unten.

[System.Web.Services.WebMethod]      
public static void MyAjaxCallingMethod(object inputs)
    {           
    string stingDataFromAjaxCall = JsonConvert.SerializeObject(inputs);
            MyObject myObj = JsonConvert.DeserializeObject<MyObject>(stingDataFromAjaxCall);
            ....}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top