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 本文介绍 ...
随机推荐
- Maximum Subarray LT53
Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...
- Android中fragment之间和Activity的传值、切换
功能介绍:通过一个activity下方的三个按钮,分别是发送消息(sendButton).聊天记录(chatButton).常用语(commonButton).当单击按钮是,来切换上方的fragmen ...
- EditText输入小数
edtValue.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
- spring学习 十三 注解AOP
spring 不会自动去寻找注解,必须告诉 spring 哪些包下的类中可能有注解,也就是要开启注解扫描,注解的包是spring-context.jar,所以在配置文件中还要引入context约束,也 ...
- python学习 day22 (3月29日)----(生成器推导式)
新手上路请多担待 1 2 封装 3 私有化封装 #__author : 'liuyang' #date : 2019/3/29 0029 上午 9:35 # 不想让别人看 修改 我的属性 # 源码来说 ...
- 数据分析报告格式zz
分析报告的输出是是你整个分析过程的成果,是评定一个产品.一个运营事件的定性结论,很可能是产品决策的参考依据,既然这么重要那当然要写好它了. 我认为一份好的分析报告,有以下一些要点: 首先,要有一个好的 ...
- 219.01.19 bzoj3252: 攻略(长链剖分+贪心)
传送门 长链剖分好题. 题意:给一棵带点权的树,可以从根节点到任一叶节点走kkk次,走过的点只能计算一次,问kkk次走过的点点权值和最大值. 思路: 考虑将整棵树带权长链剖分,这样链与链之间是不会重复 ...
- linux vi操作
1.“i”键,进入编辑状态.可以看到命令的下方出现了“--INSERT--”字样,表示成功进入了编辑模式; 2.“Esc”键,退出编辑模式.并在此时输入“:wq”以退出并保存
- MFC控件Slider Control的使用
写MFC界面程序时,今天恰好用到Slider控件,做一个小小的记录. 步骤 1.在工具栏中添加Slider Control控件: 2.在控件上右键->添加变量(Add Variable...), ...
- 在多台PC之间同步Resharper所有设置的方法
默认情况下Resharper只允许导出CodeStyle的设置,对于其它的设置不能导出,这样在不利用我们在多台PC之间同步Resharper的设置,经过多次尝试和Google找到了一种解决办法: Re ...