.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之间默认给你加上一个空格.传参时可能会应为这个空格导致服务端解析失败. 之前做接口测试时,就遇 ...
随机推荐
- GlobalSign 域名型 SSL 证书
GlobalSign 域名型 SSL 证书,支持通配符型,只验证域名所有权,属于DV 域名验证级SSL证书,无须递交书面审查资料,网上申请便捷有效率.提供40位/56位/128位,最高256位自适 ...
- N天学习一个linux命令之ping
用途 检测主机是否可到达,也就是说,目标主机是否可以联网,还可以用于检测网速.通过发送ICMP ECHO_REQUEST数据包检测. 用法 ping [options] destination 常用选 ...
- linux下的C语言开发(gdb调试)
原文: http://blog.csdn.net/feixiaoxing/article/details/7199643 用gdb调试多进程的程序会遇到困难,gdb只能跟踪一个进程(默认是跟踪父进程) ...
- string 和 vector 初探
标准库类型 string string 表示可变长的字符序列.是C++标准库类型的一部分,拥有很多优秀的性能. 定义 string 对象时如未人为初始化编译器会默认初始化为空字符串. string 对 ...
- 使用Pods和自定义静态库实现多工程联编
使用Pods和自定义静态库实现多工程联编 字数607 阅读112 评论0 喜欢0 近来随着公司项目开发的深入,项目的规范也就越来越高了,为了更加方便的管理自定义静态库与pods之间的联系,好好的研究了 ...
- hdu 4941 Magical Forest (map容器)
Magical Forest Time Limit: 24000/12000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Other ...
- Vim 复制粘贴探秘
Vim作为最好用的文本编辑器之一,使用vim来编文档,写代码实在是很惬意的事情.每当学会了vim的一个新功能,就会很大地提高工作效率.有人使用vim几十年,还没有完全掌握vim的功能,这也说明了vim ...
- Getting Installation aborted (Status 7) ApplyParsePerms: lsetfilecon of /syst...【转】
OTA升级失败:原文http://en.miui.com/thread-112197-1-1.html Do you get this "Status 7" error in Re ...
- SpringMVC之DispatcherServlet详解
SpringMVC是一种基于请求启动的WEB框架,并且使用了前端控制器的设计模式,所有满足[WEB-INF/web.xml]文件中的[url-pattern]的匹配条件的请求,这些满足的请求都会交给这 ...
- [Apple开发者帐户帮助]二、管理你的团队(2)更改团队成员角色
如果您已加入Apple开发者计划,您将在App Store Connect中管理团队成员.有关详细信息,请转到App Store Connect帮助中的添加和编辑用户. 如果您已加入Apple Dev ...