Auflösung des JSON-Array-Typs in ASP.Net-Webservices

9

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.

    
Maxim Gershkovich 06.01.2011, 05:12
quelle

5 Antworten

3

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

definieren %Vor%

und Customer mögen

%Vor%

Dann haben Sie kein Problem mit der Web-Methode AddPersonList , die wie folgt definiert ist

%Vor%

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

%Vor%

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 . Auf der Serverseite können Sie 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.

    
Oleg 08.01.2011 12:57
quelle
1

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.

    
Sean Kinsey 09.01.2011 23:41
quelle
0

Ihre Daten entsprechen nicht dem JSON-Format. Bitte versuchen Sie es mit

%Vor%

Um auf einer sicheren Seite zu sein, verwenden Sie die json-Bibliothek, um Daten in json zu konvertieren.

    
Ashish 06.01.2011 05:26
quelle
0

Nur eine Vermutung, gibt es einen führenden Platz in Ihrer Datenkette? Zwischen "und {.

%Vor%

Versuchen Sie, den Raum herauszunehmen. Irgendeine Änderung?

    
DaveB 06.01.2011 05:54
quelle
0

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.

    
Jason 13.01.2011 22:54
quelle