Beispiel zur schwach typisierten JSON-Serialisierung

Beim Serialisieren eines benutzerdefinierten Typs in ein bestimmtes Übertragungsformat oder beim Deserialisieren eines Übertragungsformats zurück in einen benutzerdefinierten Typ muss der jeweilige benutzerdefinierte Typ für den Dienst und den Client verfügbar sein. Hierzu wird normalerweise das DataContractAttribute -Attribut auf diese benutzerdefinierten Typen angewendet, und das DataMemberAttribute -Attribut wird auf ihre Member angewendet. Dieser Mechanismus wird auch beim Arbeiten mit JavaScript Object Notation (JSON)-Objekten verwendet, wie im Thema How to: Serialize and Deserialize JSON Databeschrieben.

In einigen Szenarios muss ein Windows Communication Foundation(WCF)-Dienst oder -Client auf JSON-Objekte zugreifen, die von einem Dienst oder Client außerhalb der Kontrolle des Entwicklers generiert wurden. Da immer mehr Webdienste JSON-APIs öffentlich verfügbar machen, kann es für WCF-Entwickler unpraktisch werden, lokale benutzerdefinierte Typen zu erstellen, in die beliebige JSON-Objekte deserialisiert werden.

In dem WeaklyTypedJson-Beispiel wird ein Mechanismus bereitgestellt, mit dem WCF-Entwickler mit deserialisierten beliebigen JSON-Objekten arbeiten können, ohne benutzerdefinierte Typen zu erstellen. Dies wird als schwach typisierte Deserialisierung von JSON-Objekten bezeichnet, da der Typ, in den ein JSON-Objekt deserialisiert wird, zum Zeitpunkt der Kompilierung nicht bekannt ist.

Beispielsweise gibt eine öffentliche Webdienst-API das folgende JSON-Objekt zurück, das Informationen zu einem Benutzer des Diensts enthält.

{"personal": {"name": "Paul", "age": 23, "height": 1.7, "isSingle": true, "luckyNumbers": [5,17,21]}, "favoriteBands": ["Band ABC", "Band XYZ"]}

Zum Deserialisieren dieses Objekts muss ein WCF-Client die folgenden benutzerdefinierten Typen implementieren.

[DataContract]
public class MemberProfile
 {
     [DataMember]
     public PersonalInfo personal;

     [DataMember]
     public string[] favoriteBands;
 }

 [DataContract]
public class PersonalInfo
 {
     [DataMember]
     public string name;

     [DataMember]
     public int age;

     [DataMember]
     public double height;

     [DataMember]
     public bool isSingle;

     [DataMember]
     public int[] luckyNumbers;
 }

Dies kann aufwändig sein, insbesondere, wenn der Client mehrere Typen von JSON-Objekten behandeln muss.

Der in diesem Beispiel bereitgestellte JsonObject -Typ führt eine schwach typisierte Darstellung des deserialisierten JSON-Objekts ein. JsonObject verwendet die natürliche Zuordnung zwischen JSON-Objekten und .NET Framework-Wörterbüchern und die Zuordnung zwischen JSON-Arrays und .NET Framework-Arrays. Der folgende Code veranschaulicht den JsonObject -Typ:

// Instantiation of JsonObject json omitted

string name = json["root"]["personal"]["name"];
int age = json["root"]["personal"]["age"];
double height = json["root"]["personal"]["height"];
bool isSingle = json["root"]["personal"]["isSingle"];
int[] luckyNumbers = {
                                     json["root"]["personal"]["luckyNumbers"][0],
                                     json["root"]["personal"]["luckyNumbers"][1],
                                     json["root"]["personal"]["luckyNumbers"][2]
                                 };
string[] favoriteBands = {
                                        json["root"]["favoriteBands"][0],
                                        json["root"]["favoriteBands"][1]
                                    };

Sie können JSON-Objekte und -Arrays "durchsuchen", ohne ihren Typ zum Zeitpunkt der Kompilierung deklarieren zu müssen. Eine Erläuterung der Anforderungen für das ["root"] -Objekt der obersten Ebene finden Sie im Thema Mapping Between JSON and XMLbeschrieben.

Hinweis

Die JsonObject -Klasse wird nur als Beispiel bereitgestellt. Sie wurde nicht gründlich getestet und sollte nicht in Produktionsumgebungen verwendet werden. Eine offensichtliche Implikation der schwach typisierten JSON-Serialisierung ist der Mangel an Typsicherheit beim Arbeiten mit JsonObject.

Damit der JsonObject -Typ verwendet werden kann, muss der Clientvorgangsvertrag Message als Rückgabetyp verwenden.

[ServiceContract]
    interface IClientSideProfileService
    {
        // There is no need to write a DataContract for the complex type returned by the service.
        // The client will use a JsonObject to browse the JSON in the received message.

        [OperationContract]
        [WebGet(ResponseFormat = WebMessageFormat.Json)]
        Message GetMemberProfile();
    }

JsonObject wird dann instanziiert, wie im folgenden Code dargestellt.

// Code to instantiate IClientSideProfileService channel omitted…

// Make a request to the service and obtain the Json response
XmlDictionaryReader reader = channel.GetMemberProfile().GetReaderAtBodyContents();

// Go through the Json as though it is a dictionary. There is no need to map it to a .NET CLR type.
JsonObject json = new JsonObject(reader);

Der JsonObject -Konstruktor nimmt einen XmlDictionaryReaderan, der durch die GetReaderAtBodyContents -Methode abgerufen wird. Der Reader enthält eine XML-Darstellung der vom Client empfangenen JSON-Nachricht. Weitere Informationen finden Sie im Thema Zuordnung zwischen JSON und XML.

Das Programm erzeugt die folgende Ausgabe:

Service listening at http://localhost:8000/.
To view the JSON output from the sample, navigate to http://localhost:8000/GetMemberProfile
This is Paul's page. I am 23 years old and I am 1.7 meters tall.
I am single.
My lucky numbers are 5, 17, and 21.
My favorite bands are Band ABC and Band XYZ.

So können Sie das Beispiel einrichten, erstellen und ausführen

  1. Stellen Sie sicher, dass Sie die Beispiele zum einmaligen Setupverfahren für Windows Communication Foundation ausgeführt haben.

  2. Erstellen Sie die Projektmappe "WeaklyTypedJson.sln", wie in Building the Windows Communication Foundation Samplesbeschrieben.

  3. Führen Sie die Lösung aus.