c#使用映射反序列化不同的可能的JSON到一个唯一的对象

时间:2019-01-20 05:58:03

标签: c# json.net json-deserialization

我想找到一种将多个json字符串映射到c#中的单个对象的方法。我目前在解决方案中使用Newtonsoft.Json,但我不反对使用其他方法。

这是一个使用Unit对象和不同json字符串的示例。

一般对象

public class Unit
{
    public string Year { get; set; }
    public string Model { get; set; }
}

示例json对象

{
    "UnitYear":"2018",
    "UnitModel":"F250 Super Duty"
}

{
    "AssetYear":"2019",
    "AssetModel":"Corvette Stingray"
}

如果我要通过Newtonsoft.Json反序列化方法运行每个json字符串,我希望输出像这样。

Unit1 : Year = 2018, Model = F250 Super Duty
Unit2 : Year = 2019, Model = Corvette Stingray

现在,我将映射存储在字典中,然后将其传输到数据库结构中。

private static Dictionary<string, List<KeyValuePair<string, string>>> Units = new Dictionary<string, List<KeyValuePair<string,string>>>
{
    { "0000001", new List<KeyValuePair<string,string>>
        {
            new KeyValuePair<string,string>("Year", "UnitYear"),
            new KeyValuePair<string,string>("Model", "UnitModel")
        }
    },
    { "0000002", new List<KeyValuePair<string,string>>
        {
            new KeyValuePair<string,string>("Year", "AssetYear"),
            new KeyValuePair<string,string>("Model", "AssetModel")
        }
    },
};

我发现Newtonsoft.Json有一个可以实现的客户转换器。我在网站上找到的代码非常缺乏。我确实注意到,您必须实例化自定义转换器才能传递给反序列化方法。我认为我可以使用构造函数来传递要转换的json的标识符。

Unit u1 = JsonConvert.DeserializeObject<Unit>(json, new GenericConverter("0000001"));
Unit u2 = JsonConvert.DeserializeObject<Unit>(json, new GenericConverter("0000002"));

但是我对如何利用必须重写的ReadJson感到迷茫。

这里的任何帮助将不胜感激。

谢谢

2 个答案:

答案 0 :(得分:0)

 This will be used for mapping your response to the model JsonConvert.DeserializeObject<Unit>(response)

public class Unit
{
    public string UnitYear { get; set; }
    public string UnitModel { get; set; }
}

Make sure that the property names are the same names as your json object that you are passing through 

答案 1 :(得分:0)

最佳做法是使JSON更好地描述对象:

"Unit":{
    "UnitYear":"2018",
    "UnitModel":"F250 Super Duty"
}

"Asset":{
    "AssetYear":"2019",
    "AssetModel":"Corvette Stingray"
}

现在,您可以为每个类添加一个方法:

public bool IsValid()
{
    return Model != null && Year.Date == DateTime.MinValue;
}

然后对要测试的每个类执行以下操作:

        var stringUnit = "{\"UnitYear\":\"2018\",\"UnitModel\":\"F250 Super Duty\"}";
        var assetUnit = "{\"AssetYear\":\"2019\",\"AssetModel\":\"Corvette Stingray\"}";


        var unit = Newtonsoft.Json.JsonConvert.DeserializeObject<Asset>(stringUnit);

        if (unit.IsValid())
        {
            Console.WriteLine(unit.AssetModel);
        }
        else
        {
            Console.WriteLine("Json can't convert this");
        }

我更倾向于做的事情是这样的:

创建类型Enum和单元类:

public class Unit
{
   public DateTime DateTime { get; set; }
   public string Model { get; set; }
   public UnitType UnitType { get; set; }

   public bool IsValid()
   {
       return Model != null && DateTime == DateTime.MinValue || UnitType != UnitType.Unknown;
    }
 }

然后为Newtonsoft的JSON转换器创建一个枚举:

[JsonConverter(typeof(StringEnumConverter))]
public enum UnitType
{
    Unknown = 0,
    Asset,
    Unit
}

然后您可以尝试完全相同地反序列化所有JSON:

string jsonString = "{\"Year\":\"2019\",\"Model\":\"Corvette Stingray\",\"UnitType\":\"Asset\"}";
var resultUnit = JsonConvert.DeserializeObject<Unit>(jsonString);

if (resultUnit.IsValid())
{
    // This works, do the right thing. When the type matters access resultUnit.UnitType
}
else
{
   //Throw an exception, really badly formed or an Unknown type
}