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. Html.Action和Html.RederAction来创建子视图

    1. 父视图和子视图 父视图是包含了调用返回子视图的动作方法的视图. 父视图包含大部分用于呈现页面的HTML.子视图仅包含用于展示视图某部分的必须的标记. 例如,一个子视图创建一个列表,视图可能仅仅包 ...

  2. sqlserver获取当前id的前一条数据和后一条数据

    一.条件字段为数值的情况   select * from tb where id=@id; --当前记录   select top 1 * from tb where id>@id order  ...

  3. for语句应用:乘法表

    乘法表: for语句应用: 1: 2: public class chengfa { 3: public static void main(String[] args) { 4: //int i; 5 ...

  4. MySql用statement实现DDL,DML,DQL的操作Demo

    Demo1 Connection connection=null; Statement stmt=null; int result=-1; try { Class.forName("com. ...

  5. 自定义函数标签(JSTL)

    创建自定义函数标签步骤: 1.创建类,并且方法只能是静态 public static void operation(calculator cal) 2.书写tld <taglib xmlns=& ...

  6. cas+tomcat+shiro实现单点登录-4-Apache Shiro 集成Cas作为cas client端实现

    目录 1.tomcat添加https安全协议 2.下载cas server端部署到tomcat上 3.CAS服务器深入配置(连接MYSQL) 4.Apache Shiro 集成Cas作为cas cli ...

  7. poj2187 Beauty Contest(旋转卡壳)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Beauty Contest Time Limit: 3000MS   Memor ...

  8. [每日一题] OCP1z0-047 :2013-07-25 权限――角色与对象权限

    有疑问可以去itpub讨论:http://www.itpub.net/thread-1804842-1-1.html 按题意,操作如下: 1.创建一个角色r1 sys@OCM> create r ...

  9. 利用redis协助mysql数据库搬迁

    最近公司新项目上线,需要数据库搬迁,但新版本和老版本数据库差距比较大,关系也比较复杂.如果用传统办法,需要撰写很多mysql脚本,工程量虽然不大,但对于没有dba的公司来说,稍微有点难度.本人就勉为其 ...

  10. ucos 创建 空闲任务的目的

    几乎任何操作系统都需要有空闲任务. 因为CPU(提供CPU级休眠的不算)没办法停下来,尤其是嵌入式系统这一块. CPU停下来的唯一情况就是断电了,而要保持操作系统任何时候都能及时的对外做出响应,就必须 ...