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序列化时的一些设置【测试好像没效果,疑惑】
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有两种方式处理这种情况:
- 在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的序列化的更多相关文章
- WebApi2官网学习记录---Media Formatters
Web API内建支持XML.JSON.BSON.和form-urlencoded的MiME type. 创建的自定义MIME类型要继承一下类中的一个: MediaTypeFormatter 这个类使 ...
- WebApi2官网学习记录---批量处理HTTP Message
原文:Batching Handler for ASP.NET Web API 自定义实现HttpMessageHandler public class BatchHandler : HttpMess ...
- WebApi2官网学习记录---Html Form Data
HTML Forms概述 <form action="api/values" method="post"> 默认的method是GET,如果使用GE ...
- WebApi2官网学习记录---Content Negotiation
Content Negotiation的意思是:当有多种Content-Type可供选择时,选择最合适的一种进行序列化并返回给client. 主要依据请求中的Accept.Accept-Charset ...
- WebApi2官网学习记录---Cookie
Cookie的几个参数: Domain.Path.Expires.Max-Age 如果Expires与Max-Age都存在,Max-Age优先级高,如果都没有设置cookie会在会话结束后删除cook ...
- WebApi2官网学习记录--HttpClient Message Handlers
在客户端,HttpClient使用message handle处理request.默认的handler是HttpClientHandler,用来发送请求和获取response从服务端.可以在clien ...
- WebApi2官网学习记录--HTTP Message Handlers
Message Handlers是一个接收HTTP Request返回HTTP Response的类,继承自HttpMessageHandler 通常,一些列的message handler被链接到一 ...
- WebApi2官网学习记录---Configuring
Configuration Settings WebAPI中的configuration settings定义在HttpConfiguration中.有一下成员: DependencyResolver ...
- WebApi2官网学习记录--- Authentication与Authorization
Authentication(认证) WebAPI中的认证既可以使用HttpModel也可以使用HTTP message handler,具体使用哪个可以参考一下依据: 一个HttpModel可以 ...
随机推荐
- C#如何以管理员身份运行程序(转)
在使用winform程序获取调用cmd命令提示符时,如果是win7以上的操作系统,会需要必须以管理员身份运行才会执行成功,否则无效果或提示错误. 比如在通过winform程序执行cmd命令时,某些情况 ...
- Android之来历
Android一词的本义指“机器人”,同时也是谷歌于2007年11月5日宣布的基于Linux平台的开源手机操作系统的名称,该平台由操作系统.中间件.用户界面和应用 软件组成,号称是首个为移动终端打造的 ...
- javascript 倒计时跳转.
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- oracle数据库使用plsql(64位)时出现的问题
64位win7上装PL/SQL,经常会遇见“Could not load "……\bin\oci.dll"”这个错误,我查了一下资料,原因是PL/SQL只对32位OS进行支持,解决 ...
- Javascript 判断浏览器是否为IE的最短方法
作者:idd.chiang 发布时间:April 29, 2010 分类:Javascript/AS 在网上有幸看到夷人通过IE与非IE浏览器对垂直制表符支持特性搞出的一段简短的条件: var ie ...
- css中“zoom:1”是什么意思
继承性: 无 兼容性: IE 基本语法 zoom : normal | number 语法取值 normal : 默认值.使用对象的实际尺寸 number : 百分数 | 无符号浮点实数.浮点实数 ...
- Sql数据保存到Excel文件中
public string ExportExcel( DataSet ds,string saveFileName) { try { if (ds == null) return "数据库为 ...
- ubuntu系统下adb连接手机
发现Ubuntu12.04不能连接小米开发,adb devices不能看到设备! 搞了一个上午才搞成功! 小米手机利用USB连接到Ubuntu 12.04系统.运行下面的命令: longskywan ...
- linux系统时间和硬件时钟问题(date和hwclock)
http://blog.chinaunix.net/uid-182041-id-3464524.html http://blog.csdn.net/duyiwuer2009/article/detai ...
- Win8/8.1/10获得完整管理员权限的方法
WIN+R,运行对话框中输入gpedit.msc,开启组策略,然后一步步地在“计算机配置”-“Windows 设置”-“安全设置”-“本地策略”-“安全选项”,找到右侧的“用户账户控制:以管理员批准模 ...