.NET 在序列化时使用全小写的属性名

本文介绍如何使用Newtonsoft.Json将对象属性名统一转为小写进行序列化,包括自定义NamingStrategyToLower类及ToLowerPropertyNamesContractResolver类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

解决过程

说到在 .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

转载于:https://www.cnblogs.com/yeshiyu/p/7944373.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值