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

解决过程

说到在 .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. 7.1.2 Python 内置异常类层次结构

    这一节就是拿来主义了,连接:https://blog.csdn.net/Karen_Yu_/article/details/78629918 异常名称 描述 BaseException 所有异常的基类 ...

  2. Vue 安装教程

    1.下载node.js https://nodejs.org/en/ 2.检查环境变量: npm init (初始化项目) npm i webpack vue vue-loader 安装依赖: npm ...

  3. Django——7 常用的查询 常用的模型字段类型 Field的常用参数 表关系的实现

    Django 常用的查询 常用的查询方法 常用的查询条件 常用字段映射关系 Field常用参数 表关系的实现 查用的查询方法 这是需要用到的数据 from django.http import Htt ...

  4. 【codeforces 508C】Anya and Ghosts

    [题目链接]:http://codeforces.com/contest/508/problem/C [题意] 每秒钟可以点一根蜡烛; 这根蜡烛会燃烧t秒; 然后会有m只鬼来拜访你; 要求在鬼来拜访你 ...

  5. 1414 冰雕 51nod 暴力

    1414 冰雕 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 白兰大学正在准备庆祝成立256周年.特别任命副校长 ...

  6. [bzoj4282]慎二的随机数列_动态规划_贪心

    慎二的随机数列 bzoj-4282 题目大意:一个序列,序列上有一些数是给定的,而有一些位置上的数可以任意选择.问最长上升子序列. 注释:$1\le n\le 10^5$. 想法:结论:逢N必选.N是 ...

  7. svn重新定位或checkout,提示输入用户名密码,输入后报错

    在MyEclipse中,source——>clean up.然后重新定位或checkout

  8. 【LeetCode】Longest Substring Without Repeating Characters 解题报告

    [题意] Given a string, find the length of the longest substring without repeating characters. For exam ...

  9. [RxJS 6] The Catch and Rethrow RxJs Error Handling Strategy and the finalize Operator

    Sometime we want to set a default or fallback value when network request failed. http$ .pipe( map(re ...

  10. double x = 10 ,y = 0;y = x % 2; 这个表达式正确吗?

    The remainder function and % operator. 以下这段代码过不了编译的(gcc) #include <stdio.h> #include <fenv. ...