如何获得与模型命名策略匹配的 JSON 属性 名称?

How to get a JSON property name matching the naming strategy for a model?

假设某个应用程序具有 CamelCasePropertyNamesContractResolver 的序列化程序设置,而我有一个模型:

public class Model
{
    public int Id { get; set; }

    [JsonProperty(Name = "content_text")]
    public string Text { get; set; }
}

我想找到一种方法来获取序列化程序在为每个 属性 序列化时生成的结果名称,以便满足以下条件:

string JsonName<T>(string cSharpPropertyName)
{
    //
}

JsonName<Model>(nameof(Model.Id)) == "id";
JsonName<Model>(nameof(Model.Text)) == "content_text";

我正在为自定义类型编写一个自定义反序列化器(JSON 转换器),我想将我的 Model 属性与 JSON 输入匹配而不区分大小写,但是使用当前的序列化器策略。

我有想法将包装在新 JSON 对象中的每个传入 JToken 反序列化为 c# object 并检查生成的 属性 名称,但它似乎不是很高效的。有更好的方法吗?

您可以使用合同解析器本身来完成这项工作。

让您的 JsonName 方法接受 IContractResolver 作为参数以及 属性 名称。实现可能看起来像这样:

public static string JsonName<T>(string cSharpPropertyName, IContractResolver resolver) where T : class
{
    var contract = resolver.ResolveContract(typeof(T)) as JsonObjectContract;
    var property = contract?.Properties.FirstOrDefault(p => p.UnderlyingName == cSharpPropertyName);
    return property?.PropertyName;
}

在您的 JsonConverter 中,您可以从序列化器中获取合同解析器,它作为参数提供给 ReadJson:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
    var resolver = serializer.ContractResolver;
    ...
}