认识k_BackingField,微软自己的序列化和反序列化
事情从Json的序列化和反序列化说起。
在C#2.0的项目中,以前经常使用Json.Net实现序列化和反序列化。后来从c#3.0中开始使用新增的DataContractJsonSerializer进行json相关的操作。微软提供的原生类库使用上并不复杂,参考一下msdn你很容易就会写出序列化和反序列化的方法,比如经常被人使用的泛型方法如下:
/// <summary>
/// 对象转换成json
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="jsonObject">需要格式化的对象</param>
/// <returns>Json字符串</returns>
public static string DataContractJsonSerialize<T>(T jsonObject)
{
var serializer = new DataContractJsonSerializer(typeof(T));
string json = null;
using (var ms = new MemoryStream()) //定义一个stream用来存发序列化之后的内容
{
serializer.WriteObject(ms, jsonObject);
var dataBytes = new byte[ms.Length];
ms.Position = 0;
ms.Read(dataBytes, 0, (int)ms.Length);
json = Encoding.UTF8.GetString(dataBytes);
ms.Close();
}
return json;
}
/// <summary>
/// json字符串转换成对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="json">要转换成对象的json字符串</param>
/// <returns></returns>
public static T DataContractJsonDeserialize<T>(string json)
{
var serializer = new DataContractJsonSerializer(typeof(T));
var obj = default(T);
using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(json)))
{
obj = (T)serializer.ReadObject(ms);
ms.Close();
}
return obj;
}
不过使用该类库方法的过程中还是不慎意外发现了k_BackingField。
举例之前说一下我们的一个简单的实体类Person,它有如下定义:
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime Birthday { get; set; }
}
如果Person没有附加任何特性,经测试,可以成功使用上述泛型方法进行处理。
var person = new Person { Id = 1, FirstName = "jeff", LastName = "wong", Birthday = new DateTime(1983, 8, 3) };
var json = JsonHelper.DataContractJsonSerialize<Person>(person);
Console.WriteLine(json);
var result = JsonHelper.DataContractJsonDeserialize<Person>(json);
if (result != null)
{
Console.WriteLine("{0} {1}", result.FirstName, result.LastName);
}
而且json生成是正常的字符串:
{"Birthday":"\/Date(428688000000+0800)\/","FirstName":"jeff","Id":1,"LastName":"wong"}
可是当我们把Person实体上面设置Serializable特性后,莫名,我就很不解了:
{"<Birthday>k__BackingField":"\/Date(428688000000+0800)\/","<FirstName>k__BackingField":"jeff","<Id>k__BackingField":1,"<LastName>k__BackingField":"wong"}
搜索了一下,果然早就有人发现了类似的问题。后来上stackoverflow一查,查到好像和自动属性有点关系,大家可以看一下这一篇和这一篇,而且评论比原帖精彩好像国内外大部分都是一致的。
有人说用Reflector反汇编可以看到自动属性生成的字段有前缀,可惜我一直使用ILSpy,兴致勃勃反编译查看了一下,没有没有是真的没有啊。
到这里你可能会想到,自动属性json会有k_BackingField前缀,那传统那种属性的写法呢?
[Serializable]
public class Person
{
private int id;
public int Id
{
get { return id; }
set { id = value; }
}
private string firstName;
public string FirstName
{
get { return firstName; }
set { firstName = value; }
}
private string lastName;
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
private DateTime birthday;
public DateTime Birthday
{
get { return birthday; }
set { birthday = value; }
}
}
OK,我们想一块去了,经测试,带Serializable特性的Person类,输出json一点问题没有:
{"birthday":"\/Date(428688000000+0800)\/","firstName":"jeff","id":1,"lastName":"wong"}
但是,请注意大小写(我挖了一个坑,上面的json是序列化属性吗?首字母有没有大写?)。
有没有兼容方式使自动属性输出json也正常呢?很简单,使用DataContract和DataMember属性,哪一种写法输出json都没有问题的:
[DataContract]
public class Person
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string FirstName { get; set; }
[DataMember]
public string LastName { get; set; }
[DataMember]
public DateTime Birthday { get; set; }
}
json输出带有k_BackingField前缀的问题可能非常简单,这里只是善意地提醒,我个人曾经有过“惨痛”的教训,而且感觉还相当隐蔽,大家也要小心啊。
最后,在使用.net framework自带的json有关类库的时候还碰到过特殊符号和时间格式转换的问题,网上有不少文章都讲到,相信不少人也有类似经历,这里就不说了。
参考:
http://geekswithblogs.net/sdorman/archive/2007/08/08/C-3.0-Automatic-Properties.aspx
http://stackoverflow.com/questions/945585/c-sharp-automatic-property-deserialization-of-json
http://www.cnblogs.com/goldarch/archive/2011/04/25/2027071.html
http://computeroverlord.tumblr.com/post/34781472/deserialization-problems-k-backingfield
认识k_BackingField,微软自己的序列化和反序列化的更多相关文章
- C#对 Json的序列化和反序列化时出现“k_BackingField”
在C#2.0的项目中,以前经常使用Json.NET实现序列化和反序列化.后来从c#3.0中开始使用新增的DataContractJsonSerializer进行json相关的操作.微软提供的原生类库使 ...
- Json的序列化与反序列化以及乱入的k_BackingField
0.Newtonsoft.json 最简单的最强大的基于c#的json解析库是Newtonsoft.json 在NuGet程序包管理器中在线搜索“json”,选择JSon.Net,并安装. 使用到 ...
- C# 序列化与反序列化
我们先说说什么是序列化.所谓的序列化就是把要保存的内容以特定的格式存入某种介质中.比如我们要保存一些数据在下次程序启动的时候再读入.我们一般就是把这个数据写在一个本地的文本中.然后程序启动的时候去读入 ...
- Net中JSON序列化和反序列化处理(日期时间特殊处理)
0 缘由 笔者最近在web api端使用Json.Net进行序列化处理,而在调用端使用DataContractSerializer进行反序列化,遇到日期时间处理反序列化不成功[备注:笔者使用Net ...
- C# JSON字符串序列化与反序列化
JSON与c#对象转换http://hi.baidu.com/donick/item/4d741338870c91fe97f88d33 C# JSON字符串序列化与反序列化 – http://www. ...
- 在net中json序列化与反序列化
准备好饮料,我们一起来玩玩JSON,什么是Json:一种数据表示形式,JSON:JavaScript Object Notation对象表示法 Json语法规则: 数据在键值对中 数据由逗号分隔 花括 ...
- Newtonsoft.Json高级用法,json序列号,model反序列化,支持序列化和反序列化DataTable,DataSet,Entity Framework和Entity,字符串
原文地址:https://www.cnblogs.com/yanweidie/p/4605212.html 手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口 ...
- 给Ajax一个漂亮的嫁衣——Ajax系列之五(下)之序列化和反序列化
给Ajax一个漂亮的嫁衣——Ajax系列之五(下)之序列化和反序列化 标签: ajaxdictionaryjsonobject服务器function 2012-07-25 18:41 2242人阅读 ...
- LintCode-7-二叉树的序列化和反序列化
二叉树的序列化和反序列化 设计一个算法,并编写代码来序列化和反序列化二叉树.将树写入一个文件被称为"序列化",读取文件后重建同样的二叉树被称为"反序列化". 如 ...
随机推荐
- 拓展javascript内置函数
1.获取字符串字节数 //获取字符串字节数 //方法一 /* */ String.prototype.getBytesLength = function () { var length = 0; fo ...
- HTML二(基本标签)
一.标题 HTML 标题(Heading)是通过 <h1> - <h6> 等标签进行定义的. <!--标题--> <h1>标题 1</h1> ...
- C# Console 运行之后最小化到状态栏
static void Main(string[] args) { new ConsoleCtrl(); Console.Read(); } class ConsoleCtrl { [DllImpor ...
- zookeeper工作原理解析
zookeeper一般用于distributed locking,并不适合用于distributed storage,由于zookeeper的每一个node.也叫做znode的存储容量限制是1M. z ...
- win7 mtp
Sensors MTP Monitor Service 允许MTP设备数据传输,如果该服务被禁用,MTP监视器将不能工作.该服务的默认运行方式是手动,如果你没有使用MTP设备,该功能就可以放心禁用. ...
- Hibernate3.x异常No row with the given identifier exists 解决方法
这个异常是在 多对一关系映射时,一方表中对应的数据不存在才抛出的.原来的配置: <many-to-one class="com.art.model.user.UserInfo" ...
- java instanceof和isInstance的关系 精析
1.instanceof 用途:判断这个object对象是不是这种Class类型. 语法: boolean result = object instanceof Class; 用法: 判断obje ...
- plsql oracle client没有正确安装(plsql连接远程数据库)
plsql oracle client没有正确安装(plsql连接远程数据库) CreateTime--2018年4月23日16:55:11 Author:Marydon 1.情景再现 2.问题解 ...
- Theano Logistic Regression
原理 逻辑回归的推理过程能够參考这篇文章:http://blog.csdn.net/zouxy09/article/details/20319673,当中包括了关于逻辑回归的推理,梯度下降以及pyth ...
- raise语句
# -*- coding: utf-8 -*- #python 27 #xiaodeng #Python学习手册 868 #raise语句 res=[IndexError,TypeError] #ra ...