gpt4 book ai didi

c# - 在不更改模型类的情况下,为 Json.NET 中的一个属性自定义序列化程序

转载 作者:行者123 更新时间:2023-11-30 21:31:05 25 4
gpt4 key购买 nike

我需要做类似下面的事情,但我需要在不添加属性或以其他方式污染模型类的情况下进行。理想的解决方案是通过 JsonSerializerSettings 工作,而不会干扰其他自定义序列化。顺便说一句,以下来自这个问题:Custom conversion of specific objects in JSON.NET

public class Person
{
public string FirstName { get; set; }
[JsonConverter(typeof(AllCapsConverter))]
public string LastName { get; set; }
// more properties here in the real example, some of which nest to properties that use their own JsonConverters.
}

这个玩具示例的 JsonConverter(内容并不真正相关;相关的是我将它用于属性):

public class AllCapsConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
=> objectType == typeof(string);

public override bool CanRead => false;

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotSupportedException();
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var str = value as string;
var upper = str.ToUpperInvariant();
JToken j = JToken.FromObject(upper);
j.WriteTo(writer);
}
}

通过单元测试:

public class PersonSerializationTest
{
[Fact]
public void SerializePerson_LastNameCaps()
{
var person = new Person
{
FirstName = "George",
LastName = "Washington"
};
var serialized = JsonConvert.SerializeObject(person);
var expected = @"{""FirstName"":""George"",""LastName"":""WASHINGTON""}";
Assert.Equal(expected, serialized);
}
}

最佳答案

您可以通过自定义 ContractResolver 以编程方式将 JsonConverter 应用于模型类中的一个或多个属性,而无需使用属性。这是一个非常简单的示例,它将您的 AllCapsConverter 应用于 Person 类中的 LastName 属性。 (如果您正在寻找更强大的解决方案,请查看@dbc 的 answer 。我在这里的目的是展示可能可行的最简单示例。)

public class CustomResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty prop = base.CreateProperty(member, memberSerialization);
if (prop.DeclaringType == typeof(Person) && prop.UnderlyingName == "LastName")
{
prop.Converter = new AllCapsConverter();
}
return prop;
}
}

这里是更新的测试和 Person 模型,展示了如何使用解析器:

public class PersonSerializationTest
{
[Fact]
public void SerializePerson_LastNameCaps()
{
var person = new Person
{
FirstName = "George",
LastName = "Washington"
};
var settings = new JsonSerializerSettings
{
ContractResolver = new CustomResolver()
};
var serialized = JsonConvert.SerializeObject(person, settings);
var expected = @"{""FirstName"":""George"",""LastName"":""WASHINGTON""}";
Assert.Equal(expected, serialized);
}
}

public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

工作演示:https://dotnetfiddle.net/o4e3WP

关于c# - 在不更改模型类的情况下,为 Json.NET 中的一个属性自定义序列化程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53768041/

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