.NET 在序列化时使用全小写的属性名
基于某些奇怪的需求,需要将一些对象序列化后输出,而且属性名又必须为小写形式。
解决过程
说到在 .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
}
参考
.NET 在序列化时使用全小写的属性名的更多相关文章
- 实体类双向映射进行Json序列化时出现无限循环的解决问题
1.@JsonIgnoreProperties 指定的字段不会被序列化,如下则ExamPaper的directory字段不会被序列化 @OneToMany(mappedBy = "direc ...
- java 序列化时排除指定属性
java 序列化对象如何排除指定属性呢? java 中序列化对象有多种方式:struts2 ,jackson,json-lib (1)使用struts2 json插件 依赖的jar包:struts2- ...
- Android Tips: 在给drawable中添加图片资源时,文件名必须全小写
在给drawable中添加图片资源时,文件名必须全小写
- FastJson序列化时过滤字段(属性)的方法总结
FastJson序列化时(即转成JSON字符串时),可以过滤掉部分字段,或者只保留部分字段,方法有很多,下面举一些常用的方法. 方法一.FastJson的注解 @JSONField(serialize ...
- 让 MySQL 在 Linux 下表名不区分大小写(实为表名全小写)
把 Windows 下的应用部署到 Linux 下,使用到了 Quartz 集群的特性,所以建了 MySql 的中间表,一启动看到报错: Invocation of init method faile ...
- 一个C#序列化时循环引用的问题
以前一直没搞懂为什么C#在做对象序列化时(Json序列化,XML序列化等)有时候会出现循环引用的问题,下面写了个例子,类People有一个属性引用了类Child,而类Child也有一个属性引用了类Pe ...
- Java transient关键字序列化时使用小记
1. transient的作用及使用方法 我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过 ...
- js做全选,用一个checkbox复选框做多个checkbox复选框的全选按钮,有一个复选框未被选择时,全选按钮的checked就为false
用一个checkbox复选框做多个checkbox复选框的全选按钮,有一个复选框未被选择时,全选按钮的checked就为false,当所有checkbox都被选中时,全选按钮也被选中. 详解: 有两种 ...
- JSON序列化时消除空格
使用 python 序列化时,通常使用 json.dumps()生成 json,但是会在key和value之间默认给你加上一个空格.传参时可能会应为这个空格导致服务端解析失败. 之前做接口测试时,就遇 ...
随机推荐
- Python 1 初识python
1.Python介绍 Python是一种高级语言,与JAVA C# 等同.可以编写各种应用程序,每种语言都有其合适的应用场景.而Python 的优势在于更加人性化.简便的语法规则,以及针对各种具体场景 ...
- zoj 3693
#include<stdio.h> #include<string.h>//进位问题如3.985 应该进位3.99 int main() { int n,k,i; ...
- nyoj 307
/*这是一道最短路变形题 从每个有藏宝的地方为起点 求到各个点的可以的最大重量,相当于求出了从出口 到 一个藏宝点 所 允许的最大重量,把所有藏宝点的按重量 排序(从小到大)先到最小的藏宝点带上 宝 ...
- [bzoj4003][JLOI2015]城池攻占_左偏树
城池攻占 bzoj-4003 JLOI-2015 题目大意:一颗n个节点的有根数,m个有初始战斗力的骑士都站在节点上.每一个节点有一个standard,如果这个骑士的战斗力超过了这个门槛,他就会根据城 ...
- Android简单调用相机Camera功能,实现打开照相功能
在最開始接触Android相机功能之前,先来体验一下Android调用系统照相功能吧 核心代码 Intent intent = new Intent(); //调用照相机 intent.setActi ...
- 分享修改密码的SharePoint Web part: ITaCS Change Password web part
Codeplex 上有一个现成的修改密码的Web part, 在SharePoint 2010和SharePoint 2013都可以用 项目地址:http://changepassword.codep ...
- Swift基本常识点
import Foundation // 单行注释 // 多行注释(支持嵌套,OC是不支持的) // 常量let,初始化之后就不可改变. // 常量的具体类型可以自动识别,等号后面是什么类型,它就是什 ...
- HDU 3572 Task Schedule(ISAP模板&&最大流问题)
题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=3572 题意:m台机器.须要做n个任务. 第i个任务.你须要使用机器Pi天,且这个任务要在[Si , ...
- 零基础学python-2.17 文件、open()、file()
今天我们来说说文件,以及跟文件有关的内建函数open和file 首先我们在python的根文件夹下建一个名为"123"的txt文本文件 文件中面我们输入一些文本 watermark ...
- 用sp_executesql执行动态SQL语句及获得返回值
过去我执行拼凑出来的动态SQL语句,都直接使用EXEC @sql 的方式.有好几次,都看到有资料说,应该尽量使用 sp_executesql. 究其原因,是因为仅仅参数不同的情况下,sp_execut ...