WebApi2官网学习记录---JSON与XML的序列化

JSON序列化:

WebAPI的默认序列库使用的是Json.NET,可以在Globally中配置使用DataContractJsonSerializer 进行序列化 

        protected void Application_Start()

        {

            GlobalConfiguration.Configure(WebApiConfig.Register);

            var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;

            json.UseDataContractJsonSerializer = true;

        }

默认情况下,所有的公共的属性和字段都能被序列化(非公共的不能),除非声明了JsonIgnore特性

public class Product

{

    public string Name { get; set; }

    public decimal Price { get; set; }

    [JsonIgnore]

    public int ProductCode { get; set; } // 不能被序列化

}

或者使用一下方式,将需要序列化的元素显示标出来

[DataContract]

public class Product

{

    [DataMember]

    public string Name { get; set; }

    [DataMember]

    public decimal Price { get; set; }

    public int ProductCode { get; set; }  // 不能被序列化

}

JSON序列化时的一些设置【测试好像没效果,疑惑】

WebApi2官网学习记录---JSON与XML的序列化
1  var json =  GlobalConfiguration.Configuration.Formatters.JsonFormatter;

2             //设置UTC时区

3             json.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;

4             //设置缩进

5             json.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;

6             //使用驼峰命名法

7             json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

8             //使用Microsoft JSON 时间格式("\/Date(ticks)\/")

9             json.SerializerSettings.DateFormatHandling= Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
View Code

action方法可以返回一个匿名对象,序列化成JSON(匿名对象不能序列化成XML)

 1 public object Get()

 2 {

 3     return new { 

 4         Name = "Alice", 

 5         Age = 23, 

 6         Pets = new List<string> { "Fido", "Polly", "Spot" } 

 7     };

 8 }

 9 结果:

10 {"Name":"Alice","Age":23,"Pets":["Fido","Polly","Spot"]}

 如果从client收到一个JSON格式的对象,可以反序列化这个JSON对象成Newtonsoft.Json.Linq.JObject  类型的对象【需要时POST请求】

public void Post(JObject person)

{

    string name = person["Name"].ToString();

    int age = person["Age"].ToObject<int>();

}

Note:XML序列器不支持 匿名对象和JObject实例

XML序列化: 

默认使用DataContractSerializer进行xml序列化,序列化的规则如下:

  • 所有的公共属性和字段都能被序列化,使用IgnoreDataMember 特性可以将其排除 
  • 私有和受保护的成员不会被序列化
  • 只读属性不会被序列化
  • 类和成员的名字被原样写入xml
  • 使用默认的xml命名空间

如果要更准确的控制序列化的内容,可以使用DataContract 特性,当出现了这个特性,将按如下规则进行序列化:

 

  • 只有标记了DataMember特性的字段或属性才能被序列化
  • 标记了DataMember特性的private/protected的成员也能被序列化
  • 只读属性不会被序列化
  • 改变对应的xml文件中命名空间或类的名字,使用DataContract特性
            //xml默认使用DataContractSerializer 进行序列化

            var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter;

            xml.UseXmlSerializer = true;  //使用XmlSerializer 进行序列化

            xml.Indent = true;//使用缩进

            //设置指定对象使用指定的序列化器

            xml.SetSerializer<Product>(new XmlSerializer(typeof(Product)));

移除JSON或XML序列化器    

void ConfigureApi(HttpConfiguration config)

{

    // Remove the JSON formatter

    config.Formatters.Remove(config.Formatters.JsonFormatter);



    // or



    // Remove the XML formatter

    config.Formatters.Remove(config.Formatters.XmlFormatter);

}

处理对象的循环引用

   默认情况下XML和JSON的序列化器会对对象的循环引用这种情况在序列化时抛出异常

   JSON可以使用如下方式处理:  

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;

json.SerializerSettings.PreserveReferencesHandling = 

    Newtonsoft.Json.PreserveReferencesHandling.All;

举例如下:

WebApi2官网学习记录---JSON与XML的序列化
 1 public class Employee

 2 {

 3     public string Name { get; set; }

 4     public Department Department { get; set; }

 5 }

 6 

 7 public class Department

 8 {

 9     public string Name { get; set; }

10     public Employee Manager { get; set; }

11 }

12 

13 public class DepartmentsController : ApiController

14 {

15     public Department Get(int id)

16     {

17         Department sales = new Department() { Name = "Sales" };

18         Employee alice = new Employee() { Name = "Alice", Department = sales };

19         sales.Manager = alice;

20         return sales;

21     }

22 }

23 结果:

24 {"$id":"1","Name":"Sales","Manager":{"$id":"2","Name":"Alice","Department":{"$ref":"1"}}}
View Code

  XML有两种方式处理这种情况:

  1. 在DataContract特性上设置IsReference=true                  
WebApi2官网学习记录---JSON与XML的序列化
1 [DataContract(IsReference=true)]

2 public class Department

3 {

4     [DataMember]

5     public string Name { get; set; }

6     [DataMember]

7     public Employee Manager { get; set; }

8 }
View Code

      2.创建一个针对这个对象的xml序列化器,设置允许循环引用        

WebApi2官网学习记录---JSON与XML的序列化
1 var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter;

2 var dcs = new DataContractSerializer(typeof(Department), null, int.MaxValue, 

3     false, /* preserveObjectReferences: */ true, null);

4 xml.SetSerializer<Department>(dcs);
View Code

测试对象的序列化 

WebApi2官网学习记录---JSON与XML的序列化
 1 string Serialize<T>(MediaTypeFormatter formatter, T value)

 2 {

 3     // Create a dummy HTTP Content.

 4     Stream stream = new MemoryStream();

 5     var content = new StreamContent(stream);

 6     /// Serialize the object.

 7     formatter.WriteToStreamAsync(typeof(T), value, stream, content, null).Wait();

 8     // Read the serialized string.

 9     stream.Position = 0;

10     return content.ReadAsStringAsync().Result;

11 }

12 

13 T Deserialize<T>(MediaTypeFormatter formatter, string str) where T : class

14 {

15     // Write the serialized string to a memory stream.

16     Stream stream = new MemoryStream();

17     StreamWriter writer = new StreamWriter(stream);

18     writer.Write(str);

19     writer.Flush();

20     stream.Position = 0;

21     // Deserialize to an object of type T

22     return formatter.ReadFromStreamAsync(typeof(T), stream, null, null).Result as T;

23 }

24 

25 // Example of use

26 void TestSerialization()

27 {

28     var value = new Person() { Name = "Alice", Age = 23 };

29 

30     var xml = new XmlMediaTypeFormatter();

31     string str = Serialize(xml, value);

32 

33     var json = new JsonMediaTypeFormatter();

34     str = Serialize(json, value);

35 

36     // Round trip

37     Person person2 = Deserialize<Person>(json, str);

38 }
View Code

  

你可能感兴趣的:(json)