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序列化时的一些设置【测试好像没效果,疑惑】

  var json =  GlobalConfiguration.Configuration.Formatters.JsonFormatter;
//设置UTC时区
json.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
//设置缩进
json.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
//使用驼峰命名法
json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
//使用Microsoft JSON 时间格式("\/Date(ticks)\/")
json.SerializerSettings.DateFormatHandling= Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;

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

 public object Get()
{
return new {
Name = "Alice",
Age = ,
Pets = new List<string> { "Fido", "Polly", "Spot" }
};
}
结果:
{"Name":"Alice","Age":,"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;

举例如下:

 public class Employee
{
public string Name { get; set; }
public Department Department { get; set; }
} public class Department
{
public string Name { get; set; }
public Employee Manager { get; set; }
} public class DepartmentsController : ApiController
{
public Department Get(int id)
{
Department sales = new Department() { Name = "Sales" };
Employee alice = new Employee() { Name = "Alice", Department = sales };
sales.Manager = alice;
return sales;
}
}
结果:
{"$id":"","Name":"Sales","Manager":{"$id":"","Name":"Alice","Department":{"$ref":""}}}

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

  1. 在DataContract特性上设置IsReference=true
 [DataContract(IsReference=true)]
public class Department
{
[DataMember]
public string Name { get; set; }
[DataMember]
public Employee Manager { get; set; }
}

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

 var xml = GlobalConfiguration.Configuration.Formatters.XmlFormatter;
var dcs = new DataContractSerializer(typeof(Department), null, int.MaxValue,
false, /* preserveObjectReferences: */ true, null);
xml.SetSerializer<Department>(dcs);

测试对象的序列化

 string Serialize<T>(MediaTypeFormatter formatter, T value)
{
// Create a dummy HTTP Content.
Stream stream = new MemoryStream();
var content = new StreamContent(stream);
/// Serialize the object.
formatter.WriteToStreamAsync(typeof(T), value, stream, content, null).Wait();
// Read the serialized string.
stream.Position = ;
return content.ReadAsStringAsync().Result;
} T Deserialize<T>(MediaTypeFormatter formatter, string str) where T : class
{
// Write the serialized string to a memory stream.
Stream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(str);
writer.Flush();
stream.Position = ;
// Deserialize to an object of type T
return formatter.ReadFromStreamAsync(typeof(T), stream, null, null).Result as T;
} // Example of use
void TestSerialization()
{
var value = new Person() { Name = "Alice", Age = }; var xml = new XmlMediaTypeFormatter();
string str = Serialize(xml, value); var json = new JsonMediaTypeFormatter();
str = Serialize(json, value); // Round trip
Person person2 = Deserialize<Person>(json, str);
}

WebApi2官网学习记录---JSON与XML的序列化的更多相关文章

  1. WebApi2官网学习记录---Media Formatters

    Web API内建支持XML.JSON.BSON.和form-urlencoded的MiME type. 创建的自定义MIME类型要继承一下类中的一个: MediaTypeFormatter 这个类使 ...

  2. WebApi2官网学习记录---批量处理HTTP Message

    原文:Batching Handler for ASP.NET Web API 自定义实现HttpMessageHandler public class BatchHandler : HttpMess ...

  3. WebApi2官网学习记录---Html Form Data

    HTML Forms概述 <form action="api/values" method="post"> 默认的method是GET,如果使用GE ...

  4. WebApi2官网学习记录---Content Negotiation

    Content Negotiation的意思是:当有多种Content-Type可供选择时,选择最合适的一种进行序列化并返回给client. 主要依据请求中的Accept.Accept-Charset ...

  5. WebApi2官网学习记录---Cookie

    Cookie的几个参数: Domain.Path.Expires.Max-Age 如果Expires与Max-Age都存在,Max-Age优先级高,如果都没有设置cookie会在会话结束后删除cook ...

  6. WebApi2官网学习记录--HttpClient Message Handlers

    在客户端,HttpClient使用message handle处理request.默认的handler是HttpClientHandler,用来发送请求和获取response从服务端.可以在clien ...

  7. WebApi2官网学习记录--HTTP Message Handlers

    Message Handlers是一个接收HTTP Request返回HTTP Response的类,继承自HttpMessageHandler 通常,一些列的message handler被链接到一 ...

  8. WebApi2官网学习记录---Configuring

    Configuration Settings WebAPI中的configuration settings定义在HttpConfiguration中.有一下成员: DependencyResolver ...

  9. WebApi2官网学习记录--- Authentication与Authorization

    Authentication(认证)   WebAPI中的认证既可以使用HttpModel也可以使用HTTP message handler,具体使用哪个可以参考一下依据: 一个HttpModel可以 ...

随机推荐

  1. JavaScript: Class.method vs Class.prototype.method

    在stack overflow中看到一个人回答,如下   // constructor function function MyClass () { var privateVariable; // p ...

  2. handler机制和异步更新UI页面

    Android 提供了Handler和Looper来满足线程之间的通行,Handler是先进先出原则,Looper类用来管理特定线程内对象之间的消息互换,也可以使用Runnable来完成页面异步更新 ...

  3. Sed命令学习

    1.Sed简介     流数据编辑器 Stream editer(sed),它是一种行编辑器(对应于全屏编辑器),一次处理一行的内容.默认不编辑原文件内容(-i会直接修改原文件).处理时,它先将当前符 ...

  4. uva 759 - The Return of the Roman Empire

    #include <cstdio> #include <string> #include <map> using namespace std; ; , , , , ...

  5. 学习心得记录:[一]sql安装与配置

    时间:2015年9月13日 02:43:09 科目:mysql的安装 笔记: 准备: 1.首先下载解压版的mysql 2.将下载好的文件放到c:\Program Files\MYSQL下(mysql文 ...

  6. localhost 与 127.0.0.1 的区别

    localhost与127.0.0.1的区别是什么?相信有人会说是本地ip,曾有人说,用127.0.0.1比localhost好,可以减少一次解析.看来这个入门问题还有人不清楚,其实这两者是有区别的. ...

  7. WPF、WinForm(C#)多线程编程并更新界面(UI)(转载积累)

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Drawing;using ...

  8. 在Mac上使用Nginx和FastCGI部署Flask应用

    最近在学习Flask,本文介绍一下如何部署Flask开发的应用,同时也学习一下Nginx的使用,这只是在Mac上的一个实验. 应用 这里使用的应用就是官方的文档中给出的Flaskr. 安装Nginx ...

  9. 为什么ELF文件的加载地址是0x8048000

    在一个进程的虚拟地址空间中,ELF文件是从0x8048000这个地址开始加载的,为什么会是这个地址? 回答:用命令ld --verbose可以看到0x08048000,ld的默认脚本用这个地址作为EL ...

  10. SDWebImage 官方文档

    API documentation is available at CocoaDocs - SDWebImage Using UIImageView+WebCache category with UI ...