我的困境是,我必须反序列化公司软件工程师部门提供的一些JSON文件,以便在生产环境中使用,但JSON文件的某些修订版中的对象或键的名称已被修改(例如"EngineTemp;:400到"EngTemp;:40)。
当名称不变时,我可以很容易地反序列化C#中的所有内容,但我发现自己必须修改类属性名称或类名本身,以匹配JSON修订(因为我知道它们需要相同)。然而,当修改每个JSON文件以检查名称更改时,手动读取它是非常耗时的,而且其中一些文件有数百个对象。
目前,我无法确保软件eng团队在一次又一次的修订中保持相同的名称,所以我真的希望有一种方法可以用一种不那么手动的方式来处理这个问题。
不幸的是,我不能提供JSON的任何片段,因为它是专有信息,但上面的例子基本上就是我想要解释的。
我感谢所有的建议!
如前所述,我还没有想出任何好的方法来在代码中处理这一问题,因为它处理的是更改C#中的实际类和属性名称,以在JSON中的修订被更改时匹配它们。
好的,没有真正好的解决方案,但如果他们使用的名称数量有限,那么您可以在原始json数据上使用regex,并替换为属性的名称。然后,当您反序列化时,替换的名称将起作用。
正则表达式可以很简单:
(?<=")(EngineTemp|EngTemp|OtherName)(?=":)
它只需选择一个用引号括起来并以冒号:
结尾的已知名称。
这样使用:
string json = File.ReadAllText("path");
Regex jsonRegex = new Regex(@"(?<="")(EngineTemp|EngTemp|OtherName)(?="":)";
if (!jsonRegex.IsMatch(json)
{
MessageBox.Show("ERROR", "Could not find the namenYou must scan the json manually");
}
string fixedJson = jsonRegex.Replace(json, "YourProperty");
现在,只要使用的名称在regex中,就可以在不重新编译的情况下反序列化json。
如果它们已更改为未知名称,则代码将显示一个消息框。然后找到新名称,将其添加到regex中的列表中。
编辑:
如果您想避免在找到新名称时重新编译,当然可以将列表保存在text/json文件中。然后,您只需要在找到新名称时对其进行编辑。
您可以使用Newtonsoft
反序列化为动态对象(System.Text.Json
似乎不支持动态)。
dynamic result = JsonConvert.DeserializeObject<dynamic>(inputString)!;
然后通过鸭子键入访问您的房产
result.EngTemp
或通过索引器
result["EngTemp"]
这里的重点是在您的appsettings.json中定义一个属性映射,您可以将其加载到Dictionary<string, string> mappings
中,并使用类似的东西检索属性
result[mappings["EngTemp"]]
这将通过更新appsettings.json
中的映射来实现,并且适用于无法重建应用程序或预处理输入的场景。