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. js获得url的参数

    网上找的一段代码,非常好用,现在难以找到原作者,但是非常感谢!/**   * 获取当前URL参数值  * @param name  参数名称  * @return  参数值   */ function ...

  2. sqllog 8.32 注册码

    注册信息: Name:kkkboy[CrSky] Registration code: Professional 17cb5c23-8653-418f-b81b-5582c7a5a2d7 Enterp ...

  3. RAC 常用维护工具和命令(oracle 10g)

    Oracle 的管理可以通过OEM或者命令行接口. Oracle Clusterware的命令集可以分为以下4种: 节点层:osnodes 网络层:oifcfg 集群层:crsctl, ocrchec ...

  4. .NET中常见的内存泄露问题——GC、委托事件和弱引用

    一.什么是内存泄露(memory leak)? 内存泄露不是指内存坏了,也不是指内存没插稳漏出来了,简单来说,内存泄露就是在你期待的时间内你程序所占用的内存没有按照你想象中的那样被释放. 因此什么是你 ...

  5. POJ 模拟题集合

    http://www.cppblog.com/Uriel/articles/101592.html 感觉这个暑假没有去年有激情啊,,,还没到状态就已经块上学了,,, 真是弱暴了,,,找几道模拟题刷刷. ...

  6. C程序设计语言练习题1-6

    练习1-6 验证表达式getchar() != EOF的值是0还是1. 代码如下: #include <stdio.h> // 包含标准库的信息. int main() // 定义名为ma ...

  7. Ubuntu 14.04 标题栏实时显示上下行网速、CPU及内存使用情况

    首先当然是用wget下载indicator-sysmonitor,终端执行命令:wget -c https://launchpad.net/indicator-sysmonitor/trunk/4.0 ...

  8. 关于volatile

    也许读者会注意到,端口寄存器的变量使用了volatile 修饰符,这是因为C语言在编译的时候会进行某种优化来提高效率,比如下面这段代码int i = 1;int a = i;int b = i;对于编 ...

  9. 3D打印论坛

    3D打印论坛:http://www.3done.cn http://www.03dp.com www.qjxxw.net/ http://www.3ddayin.net http://oa.zol.c ...

  10. hdu4641-K-string(后缀自动机)

    Problem Description Given a string S. K-string is the sub-string of S and it appear in the S at leas ...