gpt4 book ai didi

c# - Json.NET - ContractResolver 使用非原始键序列化字典

转载 作者:行者123 更新时间:2023-11-30 23:09:43 24 4
gpt4 key购买 nike

我有一些带有本地化文本的 .NET 类;即英语文本,相应的西类牙语文本等。我​​们有一个看起来像这样的 Locale 类:

class Locale
{
int Id;
string Abbreviation; // e.g. "en"
string Name; // e.g. "English"

static Locale FromAbbreviation(string abbreviation);
}

本地化文本存储在 IDictionary 属性中,类似于

class Document
{
IDictionary<Locale, string> Content;
}

当序列化为 JSON 时,我希望它以语言环境缩写为键,因此序列化的 Document 对象看起来像这样:

{
"content": {
"en": "English content",
"es": "Spanish content"
}
}

我需要一个 ContractResolver 来转换 IDictionary<Locale, string>反对 Dictionary<string, string>对象,在序列化期间使用 Locale.Abbreviation 属性作为键,并在反序列化时调用 Locale.FromAbbreviation() 以将键转换回 Locale 对象。

我查看了 JSON.NET 文档和各种 Stackoverflow 问题,似乎没有一种简单的方法可以做到这一点(至少我找不到)。我确实找到了看起来像 straightforward way to do the same thing using a TypeConverter attribute 的东西,但我宁愿不从我的域类中依赖 Json.NET。是否有使用 ContractResolver 执行此操作的合理方法?

最佳答案

你真的不需要 ContractResolver这里。您可以使用自定义 JsonConverter处理来自 Dictionary<Locale, string> 的转换到您想要的 JSON 并返回,而无需在模型类中使用属​​性。只要转换器的CanConvert方法被正确编码以识别转换器处理的字典类型,然后您只需将转换器添加到序列化程序设置中,Json.Net 就会找到它并适本地使用它。

这是转换器的样子:

class LocaleDictionaryConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(IDictionary<Locale, string>).IsAssignableFrom(objectType);
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject obj = JObject.Load(reader);
IDictionary<Locale, string> dict = (IDictionary<Locale, string>)existingValue ?? new Dictionary<Locale, string>();
foreach (var prop in obj.Properties())
{
dict.Add(Locale.FromAbbreviation(prop.Name), (string)prop.Value);
}
return dict;
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
IDictionary<Locale, string> dict = (IDictionary<Locale, string>)value;
JObject obj = new JObject();
foreach (var kvp in dict)
{
obj.Add(kvp.Key.Abbreviation, kvp.Value);
}
obj.WriteTo(writer);
}
}

下面是您将如何使用它进行序列化:

var settings = new JsonSerializerSettings();
settings.Converters.Add(new LocaleDictionaryConverter());
settings.Formatting = Formatting.Indented;

string json = JsonConvert.SerializeObject(document, settings);

反序列化:

// same settings as above
var document = JsonConvert.DeserializeObject<Document>(json, settings);

这是一个演示:https://dotnetfiddle.net/f1rXl2

关于c# - Json.NET - ContractResolver 使用非原始键序列化字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45695208/

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