具有继承对象的 JsonConvert DeserializeObject

JsonConvert DeserializeObject with objects with inheritance

我有这些 类

public class JsonResult
{
    [JsonProperty("name")]
    public string Name { get; set; }
    [JsonProperty("myobjects")]
    public List<BaseClass> myObjects { get; set; }
}

public abstract class BaseClass
{
    [JsonProperty("name")]
    public string Name { get; set; }
}

public class FlavourOne: BaseClass
{
    [JsonProperty("number")]
    public int Number { get; set; }
    [JsonProperty("mytext")]
    public string MyText { get; set; }
}

public class FlavourTwo: BaseClass
{
    [JsonProperty("yourtext")]
    public string YourText { get; set; }
}

我有这个 Json 对象作为一个字符串

{
"name": "examplename",
"myobjects": [
    {
        "name": "myFlavourOneInstance",
        "number": 1,
        "mytext": "Text from One"
    },
    {
        "name": "myFlavourTwoInstance",
        "yourtext": "Your Text from Two"
    }
]
}

我想从 Json 字符串中得到一个对象,如下所示

var responseObject = JsonConvert.DeserializeObject<JsonResult>(rawJsonString);

但这行不通,有没有一种简洁明了的方法可以将 json 放入具有继承 类 等的对象中?

是的,您可以使用 TypeNameHandling.Auto(或 TypeNameHandling.All,具体取决于您的用例)在 Json 中指定 class 进行反序列化。

这是一个使用 TypeNameHandling.Auto 的例子:

void Main() {
    var jsonResult = new JsonResult {
        Name = "test",
        myObjects = new List<BaseClass> {
            new FlavourOne {
                Name = nameof(FlavourOne),
                Number = 1,
                MyText = "Text from one" 
            },
            new FlavourTwo {
                Name = nameof(FlavourTwo),
                YourText = "Text from two"
            }
        }
    };
    
    var serializerSettings = new JsonSerializerSettings {
       TypeNameHandling = TypeNameHandling.Auto
    };

    var json = JsonConvert.SerializeObject(jsonResult, Formatting.Indented, serializerSettings);
    
    Console.WriteLine(json);
}

// Your classes here

输出:

{
  "name": "test",
  "myobjects": [
    {
      "$type": "FlavourOne, AssemblyName",
      "number": 1,
      "mytext": "Text from one",
      "name": "FlavourOne"
    },
    {
      "$type": "FlavourTwo, AssemblyName",
      "yourtext": "Text from two",
      "name": "FlavourTwo"
    }
  ]
}

这意味着在反序列化时,它们会被分配正确的类型,只要您使用相同的序列化程序设置即可:

var responseObject = JsonConvert.DeserializeObject<JsonResult>(json, serializerSettings);

不过请注意,根据 docs

TypeNameHandling should be used with caution when your application deserializes JSON from an external source.

这是因为你不想让外部 Json 创建任意类型!