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. win7 重启 IIS.

    步骤 1,打开 "控制面板",并将右上角的"查看方式"设置为 "大/小图标". 2,选择 "管理工具": 3,打开 In ...

  2. DataBase First创建数据库

    Entity Framework:ADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) 解决方案,并提供了三种模式,分 ...

  3. 使用DataSet数据集插入记录

    使用INSERT语句能够完成数据插入,使用DataSet对象也可以完成数据插入.为了将数据库的数据填充到DataSet中,则必须先使用DataAdapter对象的方法实现填充,当数据填充完成后,开发人 ...

  4. 使用“bulk insert ”进行批量插入数据

    本文转自csdn中文章,再次感谢他给我们分享. Bulk Insert命令详细 BULK INSERT以用户指定的格式复制一个数据文件至数据库表或视图中.语法: BULK INSERT [ [ 'da ...

  5. php 之 房屋租赁练习(0509)

    做出以下页面并实现其对应的功能: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "h ...

  6. css和js禁止网页选择文字

    user-select有两个值: none:用户不能选择文本 text:用户可以选择文本 需要注意的是:user-select并不是一个W3C的CSS标准属性,浏览器支持的不完整,需要对每种浏览器进行 ...

  7. C语言初学 判断闰年的问题

    #include<stdio.h> main( ) {  int   year , leap; scanf("%d",&year);             i ...

  8. C/C++ char和int的区别

    字符字面值一般是用一对单引号来表示.char类型一般就是用字符字面值来初始化.赋值.由于char类型的是单字节长度,当给char类型的变量用字符字面值赋值时,当单引号里面的内容超过一个字节时,系统会自 ...

  9. Cisco Anyconnect Secure Mobility Client

    Backup 进入安装文件目录cd anyconnect-3.1.00495/binary 安装sudo./vpnsetup.sh 查看安装情况ps aux  |  grep  cisco 在搜索中, ...

  10. Swift数据类型之整型和浮点型-备

    Swift提供8.16.32.64位形式的有符号及无符号整数.这些整数类型遵循C语言的命名规约,我归纳了Swift中的整型: 整型示例: print("UInt8 range: \(UInt ...