Как использовать DataContractJsonSerializer

Примечание

Эта статья посвящена DataContractJsonSerializer . В большинстве сценариев, в которых участвует сериализация и десериализация JSON, мы рекомендуем использовать интерфейсы API в пространстве имен System. Text. JSON.

JSON - эффективный формат кодирования данных, обеспечивающий быстрый обмен небольшими объемами данных между клиентскими браузерами и веб-службами с поддержкой AJAX.

В этой статье показано, как сериализовать объекты типа .NET в данные в кодировке JSON, а затем десериализовать данные в формате JSON обратно в экземпляры типов .NET. В этом примере используется контракт данных для демонстрации сериализации и десериализации определяемого пользователем Person типа и использования DataContractJsonSerializer .

как правило, сериализация и десериализация JSON автоматически обрабатываются Windows Communication Foundation (WCF) при использовании типов контрактов данных в операциях службы, которые доступны через конечные точки с поддержкой AJAX. Однако в некоторых случаях может потребоваться непосредственная работа с данными JSON.

Эта статья основана на образце DataContractJsonSerializer.

Определение контракта данных для типа Person

  1. Определите контракт данных для типа Person, применив атрибут DataContractAttribute к классу и атрибут DataMemberAttribute к элементам, которые требуется сериализовать. Дополнительные сведения о контрактах данных см. в разделе проектирование контрактов служб.

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

Сериализация экземпляра типа Person в формат JSON

Примечание

Если ошибка возникает во время сериализации исходящего ответа на сервере или по какой-либо другой причине, она может не возвращаться клиенту в качестве ошибки.

  1. Создайте экземпляр типа Person.

    var p = new Person();
    p.name = "John";
    p.age = 42;
    
  2. Сериализует Person объект в поток памяти с помощью DataContractJsonSerializer .

    var stream1 = new MemoryStream();
    var ser = new DataContractJsonSerializer(typeof(Person));
    
  3. С помощью метода WriteObject запишите данные JSON в поток.

    ser.WriteObject(stream1, p);
    
  4. Отобразите выходные данные JSON.

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

Десериализация экземпляра типа Person из формата JSON

  1. Десериализуйте данные в кодировке JSON в новый экземпляр типа Person с помощью метода ReadObject сериализатора DataContractJsonSerializer.

    stream1.Position = 0;
    var p2 = (Person)ser.ReadObject(stream1);
    
  2. Отобразите результаты.

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

Пример

// 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;
}

Примечание

Сериализатор JSON выдает исключение при сериализации контрактов данных, имеющих несколько элементов с одинаковым именем, как показано в следующем примере кода.

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

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

См. также