事情从Json的序列化和反序列化说起。

在C#2.0的项目中,以前经常使用Json.Net实现序列化和反序列化。后来从c#3.0中开始使用新增的DataContractJsonSerializer进行json相关的操作。微软提供的原生类库使用上并不复杂,参考一下msdn你很容易就会写出序列化和反序列化的方法,比如经常被人使用的泛型方法如下:

 

public class JsonHelper
{
/// <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都没有问题的:

 

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://stackoverflow.com/questions/340528/c-sharp-automatic-properties-why-do-i-have-to-write-get-set

http://www.cnblogs.com/goldarch/archive/2011/04/25/2027071.html

http://computeroverlord.tumblr.com/post/34781472/deserialization-problems-k-backingfield

转自:http://www.cnblogs.com/jeffwongishandsome/archive/2012/05/31/2529196.html

认识k_BackingField【转】的更多相关文章

  1. 认识k_BackingField,微软自己的序列化和反序列化

    事情从Json的序列化和反序列化说起. 在C#2.0的项目中,以前经常使用Json.Net实现序列化和反序列化.后来从c#3.0中开始使用新增的DataContractJsonSerializer进行 ...

  2. C#对 Json的序列化和反序列化时出现“k_BackingField”

    在C#2.0的项目中,以前经常使用Json.NET实现序列化和反序列化.后来从c#3.0中开始使用新增的DataContractJsonSerializer进行json相关的操作.微软提供的原生类库使 ...

  3. Json的序列化与反序列化以及乱入的k_BackingField

    0.Newtonsoft.json 最简单的最强大的基于c#的json解析库是Newtonsoft.json 在NuGet程序包管理器中在线搜索“json”,选择JSon.Net,并安装.   使用到 ...

  4. .NET解决[Serializable] Attribute引发的Json序列化k_BackingField

    在WebAPI中的WebApiConfig直接加入如下配置 有问题找谷歌

  5. WebApi——json返回多了 k_BackingField

    产生原因: model类添加了    [System.Serializable] 解决方案: xxxxx.WebApi\App_Start\WebApiConfig.cs的Register函数中添加如 ...

  6. [C#] C# 知识回顾 - 序列化

    C# 知识回顾 -  序列化 [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902005.html 目录 序列化的含义 通过序列化保存对象数据 众 ...

  7. .NET中那些所谓的新语法之一:自动属性、隐式类型、命名参数与自动初始化器

    开篇:在日常的.NET开发学习中,我们往往会接触到一些较新的语法,它们相对以前的老语法相比,做了很多的改进,简化了很多繁杂的代码格式,也大大减少了我们这些菜鸟码农的代码量.但是,在开心欢乐之余,我们也 ...

  8. ASP.NET MVC WEB API字段出现k__BackingField

    参考博客:C#对 Json的序列化和反序列化会出现"k_BackingField"

  9. DataContractJsonSerializer和JavaScriptSerializer内部实现差异

    定义一个下面这样的类,此类有Serializable属性,并且有一个属性的定义没有使用自动属性来实现. [Serializable] public class Users { public int U ...

随机推荐

  1. c++和java(c#)之间的pk

    个人认为本文较偏激,且年代较久远,但可以一看. 转自c++和java(c#)之间的pk 1.谁好谁坏? 如同当初我没有想到会进入java阵营一样,这次闯入c++阵营也是意料之外的.多年前,受到微软的影 ...

  2. Ikki's Story IV - Panda's Trick

    poj3207:http://poj.org/problem?id=3207 题意::平面上有一个圆,圆的边上按顺时针放着0..n-1共n个点.现在要连m条边,比如a,b,那么a到b可以从圆的内部连接 ...

  3. iOS,OC,图片相似度比较,图片指纹

    上周,正在忙,突然有个同学找我帮忙,说有个需求:图片相似度比较. 网上搜了一下,感觉不是很难,就写了下,这里分享给需要的小伙伴. 首先,本次采用的是OpenCV,图片哈希值: 先说一下基本思路: 1. ...

  4. C API向MySQL插入批量数据的快速方法——关于mysql_autocommit

    MySQL默认的数据提交操作模式是自动提交模式(autocommit).这就表示除非显式地开始一个事务,否则每个查询都被当做一个单独的事务自动执行.我们可以通过设置autocommit的值改变是否是自 ...

  5. java学习面向对象之抽象类

    什么是抽象类,之所以说抽象就是具体的反义词喽~抽象离我们最近的距离也就是初中的时候学过的美术课,抽象画派.拿一桶画彩就这么往画布上一泼,那就是抽象.那么java世界当中什么是抽象呢?我们再拿动物还有狗 ...

  6. vijosP1779国王游戏

    题目:https://vijos.org/p/1779 题解:忽然想起来我好像还没写过高精度除以单精度,于是拿这题练练手...没想到1A了... 代码: #include<cstdio> ...

  7. CentOS下安装gcc和gdb

    我的操作系统是CentOS6.4,安装源里自带了gcc4.4.0和gdb7.0,版本略老遂删除之重新安装. gcc 1.下载源码包,解压 //下载 wget http: //ftp.gnu.org/g ...

  8. Linux学习笔记2——Linux中常用文件目录操作命令

    ls 显示文件和目录列表 -l 列出文件的详细信息 -a 列出当前目录所有文件,包含隐藏文件 mkdir 创建目录 -p 父目录不存在情况下先生成父目录 cd 切换目录 touch 生成一个空文件 e ...

  9. Hibernate(五)一对一单向关联映射

    上次的博文中 Hibernate从入门到精通(四)基本映射我们已经讲解了一下基本映射和相关概念,接下来 我们会讲稍微复杂点的映射——关系映射. 关系映射分类 关系映射即在基本映射的基础上处理 多个相关 ...

  10. spring maven pom

    https://spring.io/blog/2009/12/02/obtaining-spring-3-artifacts-with-maven/