Come usare DataContractJsonSerializer

Nota

Questo articolo riguarda DataContractJsonSerializer. Per la maggior parte degli scenari che comportano la serializzazione e la deserializzazione di JSON, è consigliabile usare le API nello spazio dei nomi System.Text.Json.

JSON (JavaScript Object Notation) è un efficiente formato di codifica dati che consente scambi rapidi di piccole quantità di dati tra browser client e servizi Web compatibili con AJAX.

Questo articolo illustra come serializzare oggetti di tipo .NET in dati con codifica JSON e quindi deserializzare nuovamente i dati nel formato JSON in istanze di tipi .NET. In questo esempio viene usato un contratto dati per illustrare la serializzazione e la deserializzazione di un tipo di Person definito dall'utente e usa DataContractJsonSerializer.

In genere, la serializzazione e la deserializzazione JSON vengono gestite automaticamente da Windows Communication Foundation (WCF) quando si usano i tipi di contratto dati nelle operazioni del servizio esposte su endpoint abilitati per AJAX. In alcuni casi, tuttavia, potrebbe essere necessario usare direttamente i dati JSON.

Questo articolo si basa sull'esempio DataContractJsonSerializer.

Per definire il contratto dati per un tipo Person

  1. Definire il contratto dati per Person collegando l'oggetto DataContractAttribute alla classe e l'attributo DataMemberAttribute ai membri da serializzare. Per altre informazioni sui contratti dati, vedere Progettazione di contratti di servizio.

    [DataContract]
    internal class Person
    {
        [DataMember]
        internal string name;
    
        [DataMember]
        internal int age;
    }
    

Per serializzare un'istanza di tipo Person in JSON

Nota

Se si verifica un errore durante la serializzazione di una risposta in uscita nel server o per un altro motivo, potrebbe non essere restituito al client come errore.

  1. Creare un'istanza del tipo Person.

    var p = new Person();
    p.name = "John";
    p.age = 42;
    
  2. Serializzare l'oggetto Person in un flusso di memoria usando DataContractJsonSerializer.

    var stream1 = new MemoryStream();
    var ser = new DataContractJsonSerializer(typeof(Person));
    
  3. Utilizzare il metodo WriteObject per scrivere dati JSON nel flusso.

    ser.WriteObject(stream1, p);
    
  4. Visualizzare l'output JSON.

    stream1.Position = 0;
    var sr = new StreamReader(stream1);
    Console.Write("JSON form of Person object: ");
    Console.WriteLine(sr.ReadToEnd());
    

Per deserializzare un'istanza di tipo Person da JSON

  1. Deserializzare i dati con codifica JSON in una nuova istanza di Person utilizzando il metodo ReadObject di DataContractJsonSerializer.

    stream1.Position = 0;
    var p2 = (Person)ser.ReadObject(stream1);
    
  2. Visualizzare i risultati.

    Console.WriteLine($"Deserialized back, got name={p2.name}, age={p2.age}");
    

Esempio

// Create a User object and serialize it to a JSON stream.
public static string WriteFromObject()
{
    // Create User object.
    var user = new User("Bob", 42);

    // Create a stream to serialize the object to.
    var ms = new MemoryStream();

    // Serializer the User object to the stream.
    var ser = new DataContractJsonSerializer(typeof(User));
    ser.WriteObject(ms, user);
    byte[] json = ms.ToArray();
    ms.Close();
    return Encoding.UTF8.GetString(json, 0, json.Length);
}

// Deserialize a JSON stream to a User object.
public static User ReadToObject(string json)
{
    var deserializedUser = new User();
    var ms = new MemoryStream(Encoding.UTF8.GetBytes(json));
    var ser = new DataContractJsonSerializer(deserializedUser.GetType());
    deserializedUser = ser.ReadObject(ms) as User;
    ms.Close();
    return deserializedUser;
}

Nota

Il serializzatore JSON genera un'eccezione di serializzazione per i contratti dati che dispongono di più membri con lo stesso nome, come illustrato nel codice di esempio seguente.

[DataContract]
public class TestDuplicateDataBase
{
    [DataMember]
    public int field1 = 123;
}

[DataContract]
public class TestDuplicateDataDerived : TestDuplicateDataBase
{
    [DataMember]
    public new int field1 = 999;
}

Vedi anche