.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之间默认给你加上一个空格.传参时可能会应为这个空格导致服务端解析失败. 之前做接口测试时,就遇 ...
随机推荐
- 【Codeforces 459D】Pashmak and Parmida's problem
[链接] 我是链接,点我呀:) [题意] 定义两个函数 f和g f(i)表示a[1..i]中等于a[i]的数字的个数 g(i)表示a[i..n]中等于a[i]的数字的个数 让你求出来(i,j) 这里i ...
- PL/SQL Challenge 每日一题:2014-3-14 11gR2中带RELIES_ON子句的RESULT_CACHE函数
PL/SQL Challenge 每日一题:2014-3-14 11gR2中带RELIES_ON子句的RESULT_CACHE函数 最先答对且答案未经编辑的puber将获得纪念章一枚(答案不可编辑但可 ...
- noip模拟赛 Massacre at Béziers
题目背景 下发压缩包链接: https://pan.baidu.com/s/1geC4ooz 密码: 3vpt 所有的一切———所有的一切都被染成了红与黑. 翻卷的红莲烈焰舔舐着大地,释放出异抽的黑烟 ...
- CentOS的free命令
https://blog.csdn.net/for_tech/article/details/53044610 https://www.58jb.com/html/145.html
- Javascript中数据与字符串互转(转)
数组与字符串的相互转化 <script type="text/javascript"> var obj="new1abcdefg".replace( ...
- wait-notify模型面试题
一道面试题: 启动两个线程, 一个输出 1,3,5,7-99, 另一个输出 2,4,6,8-100 最后 STDOUT 中按序输出 1,2,3,4,5-100 错误实现1: public class ...
- HTMLParser in python
You can know form the name that the HTMLParser is something used to parse HTML files. In python, th ...
- HDU 5393
[background] 保研的事终于告一段落了,之后去北京折腾了一段时间,本以为会在那里实习一个月,谁知道刚去ICT,心中就各种反感,可能是因为LP的态度吧,否则我可能会留在那里读研也说不定.花了两 ...
- [React Testing] Confidently Ship Production React Apps
We want to make sure that when we ship new code, our users can use the application. The best way we' ...
- Implementing Software Timers - Don Libes
在看APUE习题10.5的时候提示了这篇文章,讲的非常清晰,设计也非常巧妙,所以把原文放在这里.值得自己去实现. Title: Implementing Software Timers By ...