gpt4 book ai didi

c# - 不同的 "translated"JsonProperty 名称

转载 作者:太空狗 更新时间:2023-10-29 21:37:23 24 4
gpt4 key购买 nike

我想将 JSON 中使用的键翻译成不同的语言。

我知道在设计接口(interface)、API 等时,从技术角度来看这似乎是无稽之谈。为什么不首先只使用英语?嗯,这个需求不是我写的 ;)

/// <summary>serialization language</summary>
public enum Language
{
/// <summary>English</summary>
EN,
/// <summary>German</summary>
DE
// some more ...
}

实现这一点的最简单方法可能是一个属性:

/// <summary>An Attribute to add different "translations"</summary>
public class TranslatedFieldName : Attribute
{
public string Name { get; }
public Language Lang{ get; }
// actually there might be a dictionary with lang-name pairs later on; but let's keep it simple
public TranslatedFieldName(string translatedName, Language lang)
{
this.Lang = lang;
this.Name = translatedName;
}
}

然后我将这个属性添加到我想要序列化的类中:

/// <summary>I want to serialize classes of this kind to json in different languages </summary>
public class TranslatableObject
{
[TranslatedFieldName("deutscher_schluessel", Language.DE)]
public string english_key;
}

并调用JsonConvert.SerializeObject(...)

public void SerializationMethod()
{
TranslatableObject to = new TranslatableObject()
{
english_key = "foo bar"
};
string englishJson = JsonConvert.SerializeObject(to); // == { "english_key": "foo bar" }
string germanJson = JsonConvert.SerializeObject(to, new MultiLangConverter(Language.DE); // == { "deutscher_schluessel": "foo bar" }
}

我不知道使用过的 MultiLangConverter 实际上应该是什么样子:

public class MultiLangConverter : JsonConverter
{
private readonly Language _lang,

public MultiLangConverter() : this(Language.EN) { }

public MultiLangConverter(Language lang)
{
_lang = lang;
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException("Out of scope for now");
}

public override bool CanRead
{
get { return false; } // out of scope for now
}

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
// what goes here?
}
}

我尝试过的所有尝试似乎都过于复杂。我真的需要 JsonConverter 吗?还是 ContractResolver 更适合?

最佳答案

我认为您使用属性来表示翻译后的字段名称是正确的,但我认为您最终会希望使用自定义 ContractResolver 来处理翻译而不是 JsonConverter,尤其是当您需要对多个模型类进行翻译时(似乎很有可能)。

这是解析器的样子:

public class MultiLangResolver : DefaultContractResolver
{
public Language Language { get; set; }

public MultiLangResolver(Language lang)
{
Language = lang;
}

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

// See if there is a [TranslatedFieldName] attribute applied to the property
// for the requested language
var att = prop.AttributeProvider.GetAttributes(true)
.OfType<TranslatedFieldNameAttribute>()
.FirstOrDefault(a => a.Lang == Language);

// if so, change the property name to the one from the attribute
if (att != null)
{
prop.PropertyName = att.Name;
}
return prop;
}
}

下面是如何使用解析器序列化:

public static string Serialize(object obj, Language lang)
{
var settings = new JsonSerializerSettings
{
ContractResolver = new MultiLangResolver(lang),
Formatting = Formatting.Indented
};
var json = JsonConvert.SerializeObject(obj, settings);
return json;
}

另一个注意事项:您需要使用 [AttributeUsage] 属性标记您的 TranslatedFieldNameAttribute 类,这表明它可以用于属性并且可以多次应用(针对您要支持的每种不同语言一次):

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true, Inherited = true)]
public class TranslatedFieldNameAttribute : Attribute
{
...
}

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

关于c# - 不同的 "translated"JsonProperty 名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58013457/

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