事情从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://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

认识k_BackingField,微软自己的序列化和反序列化的更多相关文章

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

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

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

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

  3. C# 序列化与反序列化

    我们先说说什么是序列化.所谓的序列化就是把要保存的内容以特定的格式存入某种介质中.比如我们要保存一些数据在下次程序启动的时候再读入.我们一般就是把这个数据写在一个本地的文本中.然后程序启动的时候去读入 ...

  4. Net中JSON序列化和反序列化处理(日期时间特殊处理)

    0  缘由 笔者最近在web api端使用Json.Net进行序列化处理,而在调用端使用DataContractSerializer进行反序列化,遇到日期时间处理反序列化不成功[备注:笔者使用Net ...

  5. C# JSON字符串序列化与反序列化

    JSON与c#对象转换http://hi.baidu.com/donick/item/4d741338870c91fe97f88d33 C# JSON字符串序列化与反序列化 – http://www. ...

  6. 在net中json序列化与反序列化

    准备好饮料,我们一起来玩玩JSON,什么是Json:一种数据表示形式,JSON:JavaScript Object Notation对象表示法 Json语法规则: 数据在键值对中 数据由逗号分隔 花括 ...

  7. Newtonsoft.Json高级用法,json序列号,model反序列化,支持序列化和反序列化DataTable,DataSet,Entity Framework和Entity,字符串

    原文地址:https://www.cnblogs.com/yanweidie/p/4605212.html 手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口 ...

  8. 给Ajax一个漂亮的嫁衣——Ajax系列之五(下)之序列化和反序列化

    给Ajax一个漂亮的嫁衣——Ajax系列之五(下)之序列化和反序列化 标签: ajaxdictionaryjsonobject服务器function 2012-07-25 18:41 2242人阅读  ...

  9. LintCode-7-二叉树的序列化和反序列化

    二叉树的序列化和反序列化 设计一个算法,并编写代码来序列化和反序列化二叉树.将树写入一个文件被称为"序列化",读取文件后重建同样的二叉树被称为"反序列化". 如 ...

随机推荐

  1. 使用js对select动态添加和删除OPTION

    <select id="ddlResourceType" onchange="getvalue(this)"> </select> 动态 ...

  2. MSP430F5438 I2C学习笔记——AT24C02

    0.前言 对于大多数单片机来说,I2C成了一个老大难问题.从51时代开始,软件模拟I2C成了主流,甚至到ARMCortex M3大行其道的今天,软件模拟I2C依然是使用最广的方法.虽然软件模拟可以解决 ...

  3. matlab histeq函数介绍

    Histeq Enhance contrast using histogram equalization 该函数通过直方图均衡化来添加对照度 Syntax J = histeq(I,hgram) De ...

  4. iOS正則表達式(一)

    什么是正則表達式? 正則表達式是对字符串操作的一种逻辑公式. 作用? 在iOS开发中我们通常使用正則表達式来匹配给定的字符串是否符合我们的业务逻辑,比方说用户注冊帐号仅仅能是手机号或者邮箱等.我们还能 ...

  5. 1z0-052 q209_2

    2: View the Exhibit to examine the output produced by the following query at three different times s ...

  6. git server

    选择Git服务器部署策略 找了一圈,发现如下方法来架设Git服务器: Git Candy:http://github.com/Aimeast/GitCandy/ AE大神的作品, Git Candy© ...

  7. 修复eclipse build-helper-maven-plugin 异常

    安装 help --> install new http://repo1.maven.org/maven2/.m2e/connectors/m2eclipse-buildhelper/0.15. ...

  8. 〖Linux〗VirtualBox修改虚拟电脑硬盘(vdi)空间大小

    1. 查看需要修改的虚拟硬盘: [scue@Link:tftpserver]$ vboxmanage list hdds UUID: 79d65850--40c3-a8e7-715b199d1673 ...

  9. C#多线程之 ManualResetEvent和AutoResetEvent

    初次体验 ManualResetEvent和AutoResetEvent主要负责多线程编程中的线程同步:以下一段是引述网上和MSDN的解析: 在.Net多线程编程中,AutoResetEvent和Ma ...

  10. MySQL C 客户端的内存泄漏问题

    我们的一个服务器软件在线上环境运行时出现了内存缓慢增长的问题. 用valgrind测试 MySQL的C客户端mysqlclient发现,它在正常的使用中会被valgrind报出存在内存泄漏. 1 正常 ...