Also habe ich herausgefunden, wie ich meine benutzerdefinierten Objekte in ASP.Net json webservices übergeben kann. Funktioniert ein Charme.
Problem, das ich habe, ist in geraden Arrays meiner benutzerdefinierten Objekte übergeben oder alternativ in Arrays, die Parameter meiner benutzerdefinierten Objekte sind.
Also zum Beispiel ...
%Vor%Fehler mit Fehler: Der Wert \ "System.Collections.Generic.Dictionary'2 [System.String, System.Object] \" ist nicht vom Typ \ "WebApplication1.WebService1 + Person \" und kann nicht verwendet werden generische Sammlung. \ r \ nParametername: value
Wie erkläre ich ASP.net, dass es sich tatsächlich um eine Gruppe von Personen handelt?
Bitte beachten Sie: Das Ändern der Funktion als Liste (der Person) oder ArrayList funktioniert, aber da ich meine eigenen benutzerdefinierten Sammlungen implementiere, ist dies für mich nicht optimal.
UPDATE: Ok, was ich bisher herausgefunden habe, ist, dass dieses Problem definitiv damit zusammenhängt, wie der JavascriptSerializer den SimpleTypeResolver benutzt, um Typen aufzulösen. Grundsätzlich wenn ich so etwas mache
%Vor%Ich kann den Fehler mithilfe des folgenden Codes neu erstellen.
%Vor%Allerdings, wenn ich meinen eigenen benutzerdefinierten Typ-Resolver in den folgenden Zeilen zur Verfügung stelle:
%Vor%Ich kann erfolgreich eine Instanz meiner benutzerdefinierten Liste erstellen.
Jetzt habe ich herausgefunden, wie ich meinen eigenen benutzerdefinierten Konverter in der Datei web.config bereitstellen kann. In Anlehnung an diese ....
%Vor%Aber das Problem ist, dass ich keinen Weg finde, einen CustomTypeResolver anzugeben. Meine Annahme ist, dass dies das einzige Teil des Puzzles ist, das ich vermisse.
PSS: Ich habe versucht, den vollständig qualifizierten Namen der Assembly zu verwenden, wie in den Dokumenten für SimpleTypeResolver ( SimpleTypeResolver MSDN ), aber dies wirft eine" Operation ist nicht gültig aufgrund des aktuellen Status des Objekts. " Ausnahme - ein Fehler, der verursacht wird, wenn der TypeResolver den Namen nicht auflösen kann (das weiß ich durch Testen mit meinem CustomTypeResolver)
UPDATE @ Oleg und Sean:
Ich bedanke mich sehr für Ihre Anregungen und habe meine Bewerbung so geändert, dass sie Ihren Vorschlägen entspricht. Ich habe gesagt, dass das Problem mit dieser Änderung darin besteht, dass meine Klassenimplementierung und das damit verbundene Verhalten auf eine Weise überarbeitet werden müssen, die ich lieber vermieden hätte.
Mein Problem bestand darin, niemals eine Liste (von Objekt) in meinen Webservice einzutragen (ich habe die Frage einfach gestellt, um sie für stackoverflow zu vereinfachen). In einem solchen Fall wäre ich bereit, eine generische Liste (von) vollständig zu akzeptieren, aber mein Problem war, dass eines meiner benutzerdefinierten Objekte eine Eigenschaft mit einer stark typisierten Liste (von) implementiert hat, also zum Beispiel:
%Vor%muss jetzt in
geändert werden %Vor%Dies ist zugegebenermaßen nicht das Ende der Welt und ist wahrscheinlich besser im Webservice-Kontext (wie Sie vorgeschlagen haben), aber definitiv ein Nachteil, wenn es um die interne Anwendungsnutzung meiner Collection-Eigenschaften geht. Das bedeutet, dass ich diese Eigenschaft entweder einmal in meine CustomCollectionList umwandeln muss, wenn ich ein erweitertes Feature verwenden möchte, oder wenn ich eine andere Eigenschaft implementieren muss, die die CustomCollectionList freigibt. Jede Lösung hinterlässt einen unangenehmen Geschmack in meinem Mund.
Zuerst die Daten
%Vor%, die Sie an den Webdienst senden, sind falsche JSON-Daten . Sie können die Daten auf Ссылка überprüfen. Korrekte JSON-Daten werden
sein %Vor%Außerdem empfehle ich Ihnen, niemals JSON manuell zu erstellen . Stattdessen sollten Sie JSON.stringify verwenden. In den meisten Fällen werden die Funktionen sogar nativ im Web unterstützt Browser (irgendwann nach Updates wie hier ). Die korrekte Serialisierung von Web-Service-Parametern kann
sein %Vor%(siehe hier für weitere Details) oder
%Vor%wo
%Vor% Welche Version der Datenrepräsentation JSON.stringify({ PersonList: t })
oder {PersonList:JSON.stringify(t)}
korrekt ist, hängt von anderen Dingen ab. Es ist einfach zu testen, welche von dort in Ihrer Umgebung funktionieren.
Nächstes kleines Problem: Sie sollten besser List(Of Person)
direkt in den Parametern von AddPersonList
anstelle der Verwendung von PersonList
verwenden, die von List(Of Person)
übernommen wurden.
AKTUALISIERT : Gerade habe ich Ihre Kommentare zu List(Of Person)
oder PersonList
zu einer anderen Antwort gelesen. Um die gleiche Diskussion zu verhindern, beschließe ich, meine Meinung dazu zu schreiben. Es ist nicht wichtig, welche Klassen Sie in Ihrem Web-Service verwenden. Sie sollten die Schnittstelle des Webdienstes so gestalten, dass sie für jede Person, die nichts über Ihre Implementierung weiß, einfach und klar sein sollte. Die Eingabedaten der Methode (zumindest was Sie in die Frage aufgenommen haben) können mit List(Of Person)
perfekt beschrieben werden. Darüber hinaus List(Of Person)
ist es gut für die Datenübertragung. Innerhalb der Methodenimplementierung können Sie List(Of Person)
in andere Klassen konvertieren, die für die Methodeninterna geeignet sind. Zum Beispiel ist es sehr einfach, PersonList
aus dem List(Of Person)
zu konstruieren. Daher empfehle ich Ihnen, dem Weg zu folgen: halten Sie die Schnittstelle des Web-Service frei von den Implementierungsdetails.
UPDATED 2 : Es ist überhaupt kein Problem, wenn das Objekt, das der Eingabeparameter der Webmethode ist, als Eigenschaft andere Objekte wie List(Of EmailAddress)
hat. Zum Beispiel, wenn Sie EmailAddress
von Ihrem letzten Beispiel als
und Customer
mögen
Dann haben Sie kein Problem mit der Web-Methode AddPersonList
, die wie folgt definiert ist
Auf die gleiche Weise können Sie
verwenden %Vor%mit
%Vor% oder viele andere Versionen von Objekten, um die Informationen mit $.ajax
an den Webserver zu senden.
Auf der Clientseite können Sie myData
wie folgt definieren
und senden Sie die Daten dann mit
an den Webserver %Vor%oder
%Vor%Alle oben genannten Arbeiten ohne Probleme. Sie können das Testbeispiel herunterladen, welches dies (Default.htm sollte gestartet werden. Um anzurufen die Methode, die Sie auf die erste oder die zweite Schaltfläche klicken sollten).
Wenn Sie sich das myData
-Objekt anschauen, das im Client-Code definiert ist, und dann die Verwendung von JSON.stringify
oben sehen, werden Sie sehen, dass Sie keine komplexen Objekte einschließlich Arrays und Eigenschaften List(Of Customer)
, List(Of EmailAddress)
oder eine Liste anderer Objekte als Repräsentationen von JavaScript-Arrays verwenden. Alles wird funktionieren. Nur Ihr ursprüngliches Beispiel mit der Objektvererbung ist schlecht.
Wenn Sie versuchen, die Schnittstelle des Web-Service von der Client-Seite und nicht von den internen Server-Strukturen zu entwerfen, werden Sie die Klassen für die entsprechenden Eingabeparameter der Web-Methoden einfach erstellen. Und alles wird sofort funktionieren. Wenn Sie Ihre internen Klassen mit den Informationen initialisieren müssen, können Sie dies sehr einfach tun. Eine solche Datenkonvertierung wird sehr einfach sein und Sie müssen keine CustomTypeResolver schreiben, die tatsächlich die gleichen sind.
UPDATE: Der erste Schritt wäre der Wechsel von .asmx zu WCFs .svc - es ist viel flexibler und sein Serializer ist viel schlauer.
Ich verwende normalerweise nur ein generisches Listenargument, das hat mich bisher nicht im Stich gelassen.
Wenn Sie eine benutzerdefinierte Eigenschaft ObjectList
anstelle einer generischen list<Object>
verwenden müssen, wie wäre es dann, die Eigenschaft ObjectList
vor der Serialisierung zu verbergen und einen list<Object>
property-Proxy zwischen den beiden zu haben?
Auf diese Weise könnte der Serializer die Eigenschaft list<Object>
serialisieren und deserialisieren, während Sie weiterhin mit der Eigenschaft ObjectList
arbeiten könnten.
Dies ist in WCF einfach mit dem DataMember
-Attribut möglich, und mit DataMember(Name='ObjectList')
können Sie sogar genau die gleichen Eigenschaftennamen in js verwenden.
Alles in allem erhalten Sie eine Eigenschaft, die sich in JavaScript als Array verhält, und als Objektliste in .net.
Obwohl Olegs Antwort ziemlich umfassend und bisher die beste ist, wollte ich einen alternativen Ansatz bieten und die .NET NewtonSoft JSON-Bibliothek empfehlen >.
Ich stimme zu, dass es gut ist, wenn Ihre Servicemethoden eine klare Definition der Parameter liefern. Wenn ich jedoch auf Probleme gestoßen bin und etwas so schnell wie möglich arbeiten musste, hat sich das Akzeptieren eines Strings und das Parsen mit dieser Bibliothek bewährt nützlich in der Prise.
Tags und Links javascript jquery asp.net vb.net webservice-client