.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之间默认给你加上一个空格.传参时可能会应为这个空格导致服务端解析失败. 之前做接口测试时,就遇 ...
随机推荐
- hdu2001 计算两点间的距离【C++】
计算两点间的距离 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- Python与常见加密方式
前言 我们所说的加密方式,都是对二进制编码的格式进行加密的,对应到Python中,则是我们的Bytes. 所以当我们在Python中进行加密操作的时候,要确保我们操作的是Bytes,否则就会报错. 将 ...
- 倍增/线段树维护树的直径 hdu5993/2016icpc青岛L
题意: 给一棵树,每次询问删掉两条边,问剩下的三棵树的最大直径 点10W,询问10W,询问相互独立 Solution: 考虑线段树/倍增维护树的直径 考虑一个点集的区间 [l, r] 而我们知道了有 ...
- Linq:Linq实例1..More
本文会不断更新应用实例. 需求1:对一个Rate列表的RateLevel属性求和,然后除以Rate列表的数量求平均值. 没有Linq的做法: Int rateLevel = ; foreach (Ra ...
- Libevent 学习笔记 (1)——Libevent 2.0安装与简单演示样例
今天開始学习Libevent . Libevent 是开源社区的一款高性能I/O框架库. 主要特点有: 1 跨平台. 2 统一事件源 3 线程安全 4 基于Reactor 今天主要进行了Libeven ...
- [CSS3] Use Sticky Positioning for Section Headers
We can take advantage of sticky positioning to keep a section header at the top of the page while th ...
- Android push推送消息到达成功率优化
Android push推送消息到达成功率优化 问题:server向client发送消息.未考虑client是否在线,这种消息到达率是非常低的. 第一次优化:使用server离线缓存数据,推断假设cl ...
- QMessageBox 的四种用法
void MainWindow::on_info_clicked() { //info QMessageBox::information(this, "Title", " ...
- LINQ Query Expressions
https://msdn.microsoft.com/en-us/library/bb397676(v=vs.100).aspx Language-Integrated Query (LINQ) is ...
- SuperSocket内置的命令行协议的解析
SuperSocket\SocketBase\Protocol\TerminatorReceiveFilter.cs /// <summary> /// Filters received ...