gpt4 book ai didi

c# - ContractResolver 可以改变映射的属性

转载 作者:行者123 更新时间:2023-11-30 15:28:32 24 4
gpt4 key购买 nike

我希望每个没有指定 JsonPropertyAttribute 的属性都遵循自定义协定。但如果它被指定,那么这正是它应该是的。

但是如果我有一个映射属性并且正在使用自定义契约解析器,那么契约解析器可以更改映射属性。

例如,当指定 JsonProperty("hello") 时,我应该在 JSON 输出中看到 hello。相反,我看到了 hello_。我提交了 issue ,但被告知改写一个更高的方法,但不是哪个方法。

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace DeserializeTest
{
class Program
{
static void Main()
{
var json = new JObject(new JProperty("hello", "world"));

var settings = new JsonSerializerSettings { ContractResolver = new CustomContractResolver() };
var a = JsonConvert.DeserializeObject<Test>(json.ToString(), settings);
}
}

public class Test
{
[JsonProperty("hello")]
public string FooBar { get; set; }
}

public class CustomContractResolver : DefaultContractResolver
{
protected override string ResolvePropertyName(string propertyName)
{
return propertyName + "_";
}
}
}

那么如何让 Json.NET 在指定时始终使用(而不是更改)JsonProperty

现实世界的例子:我正在使用 SnakeCamelCaseContractResolver .它在文本和数字之间加了一个下划线。这模仿了 Rails 序列化的方式。但在不遵循规范的情况下,例如 address1,我需要能够防止 SnakeCamelCaseContractResolver 更改属性。

最佳答案

@Andrew Whitaker 在这里有正确的想法。我要补充一点,如果你想让你的 SnakeCamelCaseContractResolver 示例工作,你可以将实现更改为以下内容。请注意,它会覆盖 CreateProperty 而不是 ResolvePropertyName

class SnakeCaseContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty prop = base.CreateProperty(member, memberSerialization);

// if the property does not have a JsonPropertyAttribute applied, use Snake Case
if (!member.CustomAttributes.Any(att => att.AttributeType == typeof(JsonPropertyAttribute)))
{
prop.PropertyName = GetSnakeCase(prop.PropertyName);
}

return prop;
}

private string GetSnakeCase(string input)
{
if (string.IsNullOrEmpty(input))
return input;

var buffer = "";

for (var i = 0; i < input.Length; i++)
{
var isLast = (i == input.Length - 1);
var isSecondFromLast = (i == input.Length - 2);

var curr = input[i];
var next = !isLast ? input[i + 1] : '\0';
var afterNext = !isSecondFromLast && !isLast ? input[i + 2] : '\0';

buffer += char.ToLower(curr);

if (!char.IsDigit(curr) && char.IsUpper(next))
{
if (char.IsUpper(curr))
{
if (!isLast && !isSecondFromLast && !char.IsUpper(afterNext))
buffer += "_";
}
else
buffer += "_";
}

if (!char.IsDigit(curr) && char.IsDigit(next))
buffer += "_";
if (char.IsDigit(curr) && !char.IsDigit(next) && !isLast)
buffer += "_";
}

return buffer;
}
}

演示:https://dotnetfiddle.net/Iqz9cA

关于c# - ContractResolver 可以改变映射的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25670901/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com