• 扩展JavaScriptSerializer之Camelcase属性名


      在Web端开发中,经常会使用到JSON作为数据源进行交互,C# 4.0中提供了JavaScriptSerializer来序列化和反序列化JSON,它在System.Web.Extension中,由于在JavaScript中,大多数的命名方式都是以Camelcase为主的,可能有些人会跟我一样,对于返回Pascal Case方式的JSON可能会比较纠结,使用过JSON.NET的博友应该知道,它提供了一个CamelCasePropertyNamesContractResolver的类,来序列化Camelcase属性名,但是JavaScriptSerializer貌似并没有提供相应的类,那么接下来我们就自己来实现支持Camelcase属性名的扩展吧。

      首先创建一个实体类,如:

    1 class Person
    2 {
    3     public int Id { get; set; }
    4 
    5     public string Name { get; set; }
    6 }

      我们先用原始的方式来看一下输入的结果,代码如下:

    1 Person person = new Person
    2 {
    3     Id = 5,
    4     Name = "aa"
    5 };
    6 JavaScriptSerializer serialize = new JavaScriptSerializer();
    7 Console.WriteLine(serialize.Serialize(person));

      输出的结果为:{"Id":5,"Name":"aa"}

      在JavaScriptSerializer中,JavaScriptConverter类的作用是提供了开发人员自定义序列化与反序列化的能力,该类是一个抽象类,关于该类的具体介绍可以查看,实现Camelcase属性名的代码如下:

    View Code
     1 public class PersonCamelcasePropertyNameConverter : JavaScriptConverter
     2 {
     3     public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
     4     {
     5         //反序列化代码
     6     }
     7 
     8     public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
     9     {
    10         return (from p in typeof(Person).GetProperties()
    11                 select new
    12                 {
    13                     name = string.Format("{0}{1}", p.Name.Substring(0, 1).ToLower(), p.Name.Substring(1)),
    14                     value = p.GetValue(obj, null)
    15                 }).ToDictionary(o => o.name, o => o.value);
    16     }
    17 
    18     public override IEnumerable<Type> SupportedTypes
    19     {
    20         get { return new Type[] { typeof(Person) }; }
    21     }
    22 }

      使用我们实现的类来重新修改一下测试代码:

    1 //上面提供的代码省略
    2 serialize.RegisterConverters(new[] { new PersonCamelcasePropertyNameConverter() });
    3 Console.WriteLine(serialize.Serialize(person));

      输出的结果为:{"id":5,"name":"aa"},达到了预期的效果,但是通过观察PersonCamelcasePropertyNameConverter的代码,我们发现其实将Person替换成泛型T也是可以成立的,而且其余的代码都不用修改,这就成了一个通用的方案了,于是再一次做了小小的调整,代码如下:

    View Code
     1 public class CamelcasePropertyNameConverter<T> : JavaScriptConverter
     2 {
     3     public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
     4     {
     5         //反序列化代码
     6     }
     7 
     8     public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
     9     {
    10         return (from p in typeof(T).GetProperties()
    11                 select new
    12                 {
    13                     name = string.Format("{0}{1}", p.Name.Substring(0, 1).ToLower(), p.Name.Substring(1)),
    14                     value = p.GetValue(obj, null)
    15                 }).ToDictionary(o => o.name, o => o.value);
    16     }
    17 
    18     public override IEnumerable<Type> SupportedTypes
    19     {
    20         get { return new Type[] { typeof(T) }; }
    21     }
    22 }

      调整一下Person类并调整代码,代码如下:

     1 class Person
     2 {
     3     public int Id { get; set; }
     4 
     5     public string Name { get; set; }
     6 
     7     public Company Company { get; set; }
     8 }
     9 
    10 class Company
    11 {
    12     public string Name { get; set; }
    13 }
    14 
    15 //测试代码
    16 
    17 Person person = new Person
    18 {
    19     Id = 5,
    20     Name = "ahl5esoft",
    21     Company = new Company
    22     {
    23         Name = "5esoft"
    24     }
    25 };
    26 JavaScriptSerializer serialize = new JavaScriptSerializer();
    27 serialize.RegisterConverters(new JavaScriptConverter[] { 
    28     new CamelcasePropertyNameConverter<Person>(), 
    29     new CamelcasePropertyNameConverter<Company>() });
    30 
    31 Console.WriteLine(serialize.Serialize(person));

      输出结果为:{"id":5,"name":"ahl5esoft","company":{"name":"5esoft"}}

      如果想简化JavaScriptSerializer的调用,可以自己对其创建相应的扩展方法。

      文章就到这里了,以上如有错误和不足请指出,谢谢!

  • 相关阅读:
    递归函数底层原理浅析
    lambda expression & mutable
    命令mv
    printf的参数
    程序结构之静态本地变量
    汇编.align指令
    程序结构之全局变量
    命令touch
    更改gcc默认版本,实现gcc版本升降级
    命令chmod
  • 原文地址:https://www.cnblogs.com/ahl5esoft/p/3022313.html
Copyright © 2020-2023  润新知