C#实现动态模型:基于JSON自动更新多语言消息模型
问题描述
我有一个存储应用内所有消息的JSON文件,示例如下:
{ "MSG_1": { "en":"Something went wrong, please try again later", "ar":"..." }, "MSG_2": { "en": "User created successfully", "ar": "..." }, "MSG_3": { "en": "Phone number already exists", "ar": "..." }, "MSG_4": { "en": "Validation Error, Fix it then try again", "ar": "..." } }
目前我将该JSON解析为Dictionary<string, Dictionary<string, string>>类型变量,通过jsonValues["MSG_1"]["en"]读取值,但这种方式容易出现拼写错误。我希望将JSON转换为C#模型使用,且JSON更新时模型能自动同步。
我已编写初步模型类:
public class BusinessMessagesModel{ // 希望能自动添加其他消息属性 public MSGModel Msg {set; get;} } public class MSGModel{ public required string En {get; set;} public required string Ar {get; set;} }
期望实现类似string value = businessMessagesModel.MSG_1.en;的调用方式,输出结果为Something went wrong, please try again later。
解决方案
方法1:System.Text.Json源代码生成器(推荐,编译时强类型检查)
这种方式能在编译阶段根据JSON文件自动生成强类型模型,JSON更新后重新编译即可同步模型,彻底避免拼写错误。
步骤
- 确保项目使用.NET 6+(内置
System.Text.Json,低版本需安装对应NuGet包)。 - 将JSON文件(如
messages.json)的属性设置为复制到输出目录(始终复制或较新时复制)。 - 创建序列化上下文配置类:
using System.Text.Json.Serialization; [JsonSourceGenerationOptions(WriteIndented = true)] [JsonSerializable(typeof(BusinessMessages))] public partial class BusinessMessagesJsonContext : JsonSerializerContext { }
- 定义消息项模型,并让主模型类由源代码生成器自动填充属性:
public class MessageItem { [JsonPropertyName("en")] public required string En { get; set; } [JsonPropertyName("ar")] public required string Ar { get; set; } } // 源代码生成器会自动根据JSON生成MSG_1、MSG_2等属性 public partial class BusinessMessages { }
- 反序列化并使用:
string jsonContent = File.ReadAllText("messages.json"); var businessMessages = JsonSerializer.Deserialize( jsonContent, BusinessMessagesJsonContext.Default.BusinessMessages ); // 强类型调用,编译时检查拼写 string errorMsg = businessMessages.MSG_1.En;
方法2:T4模板生成静态类(灵活可控)
通过T4模板在编译时读取JSON,自动生成包含所有消息的静态类,适合需要自定义生成逻辑的场景。
- 添加T4模板文件(如
Messages.tt):
<#@ template debug="false" hostspecific="true" language="C#" #> <#@ assembly name="System.Core" #> <#@ assembly name="Newtonsoft.Json" #> <#@ import namespace="System.IO" #> <#@ import namespace="System.Collections.Generic" #> <#@ import namespace="Newtonsoft.Json" #> <# // 替换为你的JSON文件路径 string jsonPath = Host.ResolvePath("messages.json"); string jsonContent = File.ReadAllText(jsonPath); var messages = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(jsonContent); #> namespace YourAppNamespace; public static class BusinessMessages { <# foreach (var kvp in messages) { #> public static readonly MessageItem <#= kvp.Key #> = new MessageItem { En = "<#= kvp.Value["en"].Replace("\"", "\\\"") #>", Ar = "<#= kvp.Value["ar"].Replace("\"", "\\\"") #>" }; <# } #> } public class MessageItem { public string En { get; init; } public string Ar { get; init; } }
- 设置模板文件属性,确保编译时自动重新生成。
- 使用方式:
string successMsg = BusinessMessages.MSG_2.En;
方法3:动态类型(不推荐,无编译检查)
如果只是临时测试,可以用dynamic类型直接读取,但无法避免拼写错误,运行时才会暴露问题:
dynamic businessMessages = JsonSerializer.Deserialize<dynamic>(jsonContent); string duplicatePhoneMsg = businessMessages.MSG_3.en;
内容的提问来源于stack exchange,提问作者Khalid Mohammed
相关产品推荐
相关产品推荐

