ASP.NET WebAPI (反)序列化用[SerializableAttribute]修饰的类的一个坑
发现问题
在 ASP.NET WebAPI 项目中,有这样的 ViewModel 类:
[Serializable]
class Product
{
public int Id { get; set; }
public decimal Price { get; set; }
public DateTime ProductDate { get; set; }
}
Controller 和 Action 代码如下:
public class ProductController : ApiController
{
public Product Get(int id)
{
return new Product()
{
Id = 1,
Price = 12.9m,
ProductDate = new DateTime(1992, 1, 1)
};
}
}
客户端请求该资源: http://localhost:5000/api/product/1,结果发现 WebAPI 返回这样的JSON,如下:
{
"<Id>k__BackingField": 1,
"<Price>k__BackingField": 12.9,
"<ProductDate>k__BackingField": "1992-01-01T00:00:00"
}
我们知道,自动属性虽然没有定义字段,但是C#编译器会生成相应的私有字段,类似 private int <Id>k__BackingField。
我们期望 WebAPI 序列化时将属性名作为 JSON 的键,而这里 WebAPI 序列化的却是编译器生成的私有字段,显然不符合我们的要求。
奇怪的地方是,如果单独用 Json.NET 类库去序列化,则能得到期望的 JSON,如下:
{
"Id": 1,
"Price": 12.9,
"ProductDate": "1992-01-01T00:00:00"
}
找到原因
经过 Google 一番,原来是和 SerializableAttribute 有关。
从 Json.NET 4.5 Release 2 版本开始,新增这样的特性:
如果检测到类型有 SerializableAttribute,将序列化该类型的所有私有/公开字段,并且忽略其属性。
如果不想要这个新特性,可以对类应用 JsonObjectAttribute 来覆盖,或者在全局范围内 设置 DefaultContractResolver 的 IgnoreSerializableAttribute 为 true。
而从 release 3 版本开始 IgnoreSerializableAttribute 默认为 true。
而 ASP.NET WebAPI 依赖 Json.NET,但是却将 IgnoreSerializableAttribute 设置为 false,也就是不忽略 SerializableAttribute,导致如果类用 [SerializableAttribute] 修饰,就只(反)序列化字段而忽略属性,于是当用自动属性时,输出的就是编译器自动生成的字段名。
解决问题
了解到问题的原因后,可以通过以下方式解决:
- 去掉 [Serializable]
- 应用 [JsonObjectAttribute]
- 设置 IgnoreSerializableAttribute
最简单的方法就是去掉 [Serializable],如果由于某些原因不能去除,可以用其他两种办法。
应用 JsonObjectAttribute
[Newtonsoft.Json.JsonObject]
[System.Serializable]
class Product
{
public int Id { get; set; }
public decimal Price { get; set; }
public DateTime ProductDate { get; set; }
}
设置 IgnoreSerializableAttribute
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// 其他代码省略 .........
// 将 SerializerSettings 重置为默认值 IgnoreSerializableAttribute = true
config.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings();
}
}
参考:
Json.NET 4.5 Release 2 – Serializable support and bug fixes
Why won't Web API deserialize this but JSON.Net will?
ASP.NET WebAPI (反)序列化用[SerializableAttribute]修饰的类的一个坑的更多相关文章
- 细说Asp.Net WebAPI消息处理管道
我们在开发完Asp.Net WebAPI程序后,可以使用WebHost寄宿方式或者SelfHost寄宿方式来部署Asp.Net WebAPI.所谓WebHost寄宿就是通过Asp.Net来实现:所谓S ...
- ASP.NET WebAPI使用Swagger生成测试文档
ASP.NET WebAPI使用Swagger生成测试文档 SwaggerUI是一个简单的Restful API测试和文档工具.简单.漂亮.易用(官方demo).通过读取JSON配置显示API .项目 ...
- ASP.NET WebAPI 测试文档 (Swagger)
ASP.NET WebAPI使用Swagger生成测试文档 SwaggerUI是一个简单的Restful API测试和文档工具.简单.漂亮.易用(官方demo).通过读取JSON配置显示API .项目 ...
- 笔记-ASP.NET WebApi
本文是针对ASP.NET WepApi 2 的笔记. Web API 可返回的结果: 1.void 2.HttpResponseMessage 3.IHttpActionResult 4.其他类型 返 ...
- Asp.Net WebApi核心对象解析(下篇)
在接着写Asp.Net WebApi核心对象解析(下篇)之前,还是一如既往的扯扯淡,元旦刚过,整个人还是处于晕的状态,一大早就来处理系统BUG,简直是坑爹(好在没让我元旦赶过来该BUG),队友挖的坑, ...
- 【开源】分享一个前后端分离方案-前端angularjs+requirejs+dhtmlx 后端asp.net webapi
一.前言 半年前左右折腾了一个前后端分离的架子,这几天才想起来翻出来分享给大家.关于前后端分离这个话题大家也谈了很久了,希望我这个实践能对大家有点点帮助,演示和源码都贴在后面. 二.技术架构 这两年a ...
- 前端angularjs+requirejs+dhtmlx 后端asp.net webapi
享一个前后端分离方案源码-前端angularjs+requirejs+dhtmlx 后端asp.net webapi 一.前言 半年前左右折腾了一个前后端分离的架子,这几天才想起来翻出来分享给大家 ...
- Asp.Net WebApi核心对象解析(二)
在接着写Asp.Net WebApi核心对象解析(下篇)之前,还是一如既往的扯扯淡,元旦刚过,整个人还是处于晕的状态,一大早就来处理系统BUG,简直是坑爹(好在没让我元旦赶过来该BUG),队友挖的坑, ...
- [翻译] ASP.NET WebAPI 中的异常处理
原文链接:https://docs.microsoft.com/en-us/aspnet/web-api/overview/error-handling/exception-handling 本文介绍 ...
随机推荐
- java多线程知识点
下面是我学习多线程记录的知识点,并没详细讲解每个知识点,只是将重要的知识点记录下来,有时间可以看看,如果有不对的地方,欢迎大家指出,谢谢! 1.多线程的状态和创建方式: 线程的状态: ...
- [C#.Net]判断文件是否被占用的两种方法
今天开发产线测试Tool时发现日志文件会几率性的被占用,上网浏览找到最简单的代码(API或者FileStream),在这里抛砖引玉下. 第一种方法:API using System.IO; using ...
- 【C#】解析C#中JSON.NET的使用
目录结构: contents structure [-] JSON.NET简介 Serializing and Deserializing JSON Json Convert Json Seriali ...
- 7月底的list
多校的新姿势: 超大数比较 置换群 树归 莫比乌斯反演 7月26日做了的list: a.补了多校的两道题. b.学了如何比较特别多特别大的数 c.看了波循环群 d.看了点kmp 7月27想做的li ...
- MySQL查找SQL耗时瓶颈 SHOW profiles
http://blog.csdn.net/k_scott/article/details/8804384 1.首先查看是否开启profiling功能 SHOW VARIABLES LIKE '%pro ...
- 使用tensorflow下的GPU加速神经网络训练过程
下载CUDA8.0,安装 下载cuDNN v5.1安装.放置环境变量等. 其他版本就不装了.不用找其他版本的关系. 使用tensorflow-gpu1.0版本. 使用keras2.0版本. 有提示的. ...
- 58.UIScrollView XIB拖拽约束
第一步: 拖拽UIScrollView 到控制器上 ,给scrollView 添加约束 ,这时是正常的 第二步:scrollview上添加UIview ,(注意:这个 ScrollView就是根据这个 ...
- mysql字符串类型数据
字符串类型是在数据库中存储字符串的数据类型,字符串类型包括char,varchar,text,enum和set. OK,我们来一个一个的看下上面提到的几种类型. char类型和varchar类型 ch ...
- 2018.12.18 bzoj5296: [Cqoi2018]破解D-H协议(bsgs)
传送门 bsgsbsgsbsgs基础题. 考虑到给的是原根,因此没无解的情况. 于是只需要每次把a,ba,ba,b解出来. 然后可以通过预处理节省一部分时间. 代码: #include<bits ...
- poj-3928(树状数组)
题目链接:传送门 题意:n个乒乓球运动员要互相练习,都去一个运动员那里比赛,举办训练的运动员不能水平最高或最低. 现在给出n个运动员的水平,求出最终有多少种组合. 思路:先对运动员进行离散化,然后进行 ...