基于某些奇怪的需求,需要将一些对象序列化后输出,而且属性名又必须为小写形式。

解决过程

说到在 .NET 平台上序列化操作,那么第一个想到的应该就是 Json.NET 家的 Newtonsoft.Json 啦。

首先,我们有这么一个需要序列化的对象。

public class Demo
{
public int Id { get; set; } public string PrimaryKey { get; set; } public int WwW { get; set; }
}

那么,我们在平常一般使用时会使用 [JsonProperty(PropertyName="xxx")][JsonIgnore] 等属性来进行一些简单的调整,如下。

public class Demo
{
[JsonProperty(PropertyName="id")]
public int Id { get; set; } [JsonProperty(PropertyName="primarykey")]
public string PrimaryKey { get; set; } [JsonProperty(PropertyName="www")]
public int WwW { get; set; }
}

当然这样是可以实现最终效果的,但是当有相当多个地方需要使用小写的属性名时,这么做显然是很坑的 = =

于是,通过各种翻查资料,我发现了一个 Newtonsoft.Json 自带的 CamelCasePropertyNamesContractResolver 类 —— 在序列化时使用驼峰式命名来代替默认的命名方式。

string json = JsonConvert.SerializeObject(
new Demo { Id = 1, PrimaryKey = "Poi", WwW = 233 },
new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }
);

如此序列化,输出结果为 { id:1, primaryKey:"Poi", wwW:233 }

显然,这也并不是我们需要的。

不过,观察上面的代码,我们也可以发现 ContractResolver 属性可以自定义格式化序列化后的返回值,而 CamelCasePropertyNamesContractResolver 则继承自 DefaultContractResolver

于是我们定位到 DefaultContractResolver 下,又会发现有一个 NamingStrategy 属性,其介绍为 Gets or sets the naming strategy used to resolve how property names and dictionary keys are serialized. 是的,这就是我们需要进行重写的类。

public class NamingStrategyToLower : NamingStrategy
{
/// <summary>
/// Resolves the specified property name.
/// </summary>
/// <param name="name">The property name to resolve.</param>
/// <returns>The resolved property name.</returns>
protected override string ResolvePropertyName(string name)
{
return name.ToLower();
}
}

显而易见的,我们可以发现这个 ResolvePropertyName(string name) 就是我们需要 override 的方法,而我们需要做的也仅仅只是 return name.ToLower() 将属性名以小写的方式返回而已。

于是,我们最终的调用与输出结果如下。

class Program
{
static void Main(string[] args)
{
string json = JsonConvert.SerializeObject(
new Demo { Id = 1, PrimaryKey = "Poi", WwW = 233 },
Formatting.Indented,
new JsonSerializerSettings { ContractResolver = new ToLowerPropertyNamesContractResolver() }
);
Console.WriteLine(json);
// output
// {
// id:1,
// primarykey:"Poi",
// www:233
// }
Console.ReadKey();
}
} public class ToLowerPropertyNamesContractResolver : DefaultContractResolver
{
public ToLowerPropertyNamesContractResolver()
{
base.NamingStrategy = new NamingStrategyToLower();
}
} public class NamingStrategyToLower : NamingStrategy
{
/// <summary>
/// Resolves the specified property name.
/// </summary>
/// <param name="name">The property name to resolve.</param>
/// <returns>The resolved property name.</returns>
protected override string ResolvePropertyName(string name)
{
return name.ToLower();
}
}

嗯,全部完成。

额外扩展

细心的pong友们应该发现了,我们使用了 SerializeObject(object value, Formatting formatting, JsonSerializerSettings settings) 的重载来代替之前的 SerializeObject(object value, JsonSerializerSettings settings) 方法。

/// <summary>
/// Specifies formatting options for the Newtonsoft.Json.JsonTextWriter.
/// </summary>
public enum Formatting
{
/// <summary>
/// No special formatting is applied. This is the default.
/// </summary>
None = 0, /// <summary>
/// Causes child objects to be indented according to the Newtonsoft.Json.JsonTextWriter.Indentation and Newtonsoft.Json.JsonTextWriter.IndentChar settings.
/// </summary>
Indented = 1
}

从介绍可知,Formatting.Indented 可以帮助我们更加“视觉化”的输出 json

// Formatting.None 也就是默认值
{ id:1, primarykey:"Poi", www:233 } // Formatting.Indented,格式化输出
{
id:1,
primarykey:"Poi",
www:233
}

参考

  1. Serialization Attributes
  2. Serialization using ContractResolver
  3. DefaultContractResolver Class

.NET 在序列化时使用全小写的属性名的更多相关文章

  1. 实体类双向映射进行Json序列化时出现无限循环的解决问题

    1.@JsonIgnoreProperties 指定的字段不会被序列化,如下则ExamPaper的directory字段不会被序列化 @OneToMany(mappedBy = "direc ...

  2. java 序列化时排除指定属性

    java 序列化对象如何排除指定属性呢? java 中序列化对象有多种方式:struts2 ,jackson,json-lib (1)使用struts2 json插件 依赖的jar包:struts2- ...

  3. Android Tips: 在给drawable中添加图片资源时,文件名必须全小写

    在给drawable中添加图片资源时,文件名必须全小写

  4. FastJson序列化时过滤字段(属性)的方法总结

    FastJson序列化时(即转成JSON字符串时),可以过滤掉部分字段,或者只保留部分字段,方法有很多,下面举一些常用的方法. 方法一.FastJson的注解 @JSONField(serialize ...

  5. 让 MySQL 在 Linux 下表名不区分大小写(实为表名全小写)

    把 Windows 下的应用部署到 Linux 下,使用到了 Quartz 集群的特性,所以建了 MySql 的中间表,一启动看到报错: Invocation of init method faile ...

  6. 一个C#序列化时循环引用的问题

    以前一直没搞懂为什么C#在做对象序列化时(Json序列化,XML序列化等)有时候会出现循环引用的问题,下面写了个例子,类People有一个属性引用了类Child,而类Child也有一个属性引用了类Pe ...

  7. Java transient关键字序列化时使用小记

    1. transient的作用及使用方法 我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过 ...

  8. js做全选,用一个checkbox复选框做多个checkbox复选框的全选按钮,有一个复选框未被选择时,全选按钮的checked就为false

    用一个checkbox复选框做多个checkbox复选框的全选按钮,有一个复选框未被选择时,全选按钮的checked就为false,当所有checkbox都被选中时,全选按钮也被选中. 详解: 有两种 ...

  9. JSON序列化时消除空格

    使用 python 序列化时,通常使用 json.dumps()生成 json,但是会在key和value之间默认给你加上一个空格.传参时可能会应为这个空格导致服务端解析失败. 之前做接口测试时,就遇 ...

随机推荐

  1. SCI 论文金句

    SCI 不会写?其实英语基础好一点,文献多看一点,多写写自然就能自己写出来了.当然,你肯定会说英语真的好难,好吧,就知道你们懒得学英语了.我给你们整理了一套万能模板,涵盖了论文不同部分的常用句型. 摘 ...

  2. vue 使用echarts

    import echarts from 'echarts'   <div id="kocGrow" style="width: 600px;height: 300p ...

  3. noip模拟赛 第k大区间

    [问题描述] 定义一个长度为奇数的区间的值为其所包含的的元素的中位数. 现给出n个数,求将所有长度为奇数的区间的值排序后,第K大的值为多少. [输入] 输入文件名为kth.in. 第一行两个数n和k ...

  4. hdu_1859_最小长方形_201402282048

    最小长方形 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  5. [bzoj1812][IOI2006]riv_多叉树转二叉树_树形dp

    riv bzoj-1812 IOI-2006 题目大意:给定一棵n个点树,要求在上面建立k个收集站.点有点权,边有边权,整棵树的代价是每个点的点权乘以它和它的最近的祖先收集站的距离积的和. 注释:$1 ...

  6. 完全卸载VS2013的方法

    解压安装包的ISO文件,然后进入到根目录运行命令行: vs_ultimate.exe /uninstall /force 注意:比如ISO是Update 5的,那么卸载的只能是Update 5安装的内 ...

  7. java 的collection

    参考:http://skyuck.iteye.com/blog/526358 https://www.tutorialspoint.com/java/java_collections.htm Prio ...

  8. Kotlin和Java名称的由来

    Kotlin和Java名称的由来 学习了:http://blog.jobbole.com/111249/ JetBrains由战斗民族开发: Java来源于印尼群岛中的Java岛: Kotlin来源于 ...

  9. edittext禁止android软键盘弹出

    1. EditText ed=(EditText) findViewById(R.id.test); ed.clearFocus(); 2. 在AndroidMainfest.xml中选择哪个acti ...

  10. Lightoj 1235 - Coin Change (IV) 【二分】

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1235 题意: 有N个硬币(N<=18).问是否能在每一个硬币使用不超过两 ...