如何使用 DataContractJsonSerializer

注意

本文介绍 DataContractJsonSerializer。 对于涉及序列化和反序列化 JSON 的大多数方案,我们建议使用 System.Text.Json 命名空间中的 API。

JSON(JavaScript 对象符号)是一种高效的数据编码格式,可用于在客户端浏览器和支持 AJAX 的 Web 服务之间快速交换少量数据。

本文演示如何将 .NET 类型对象序列化为 JSON 编码数据,然后将 JSON 格式的数据反序列化为 .NET 类型的实例。 本示例使用数据协定来演示用户定义的 Person 类型的序列化和反序列化,并使用 DataContractJsonSerializer

通常,在通过支持 AJAX 的终结点公开的服务操作中使用数据协定类型时,Windows Communication Foundation (WCF) 会自动处理 JSON 序列化和反序列化。 但是,在某些情况下你可能需要直接处理 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. 使用 DataContractJsonSerializerPerson 对象序列化为内存流。

    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());
    

从 JSON 反序列化 Person 类型的实例

  1. 通过使用 PersonReadObject 方法,将 JSON 编码数据反序列化为一个新的 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;
}

另请参阅