将嵌套类反序列化为基本属性类型

本文关键字:属性 类型 嵌套 反序列化 | 更新日期: 2023-09-27 18:15:37

我有一个示例json,看起来像:

{
    "isError": false,
    "Status": 0,
    "Message": "The request processed successfully.",
    "Result": [
        {
            "EmployeeId": {
                "DisplayValue": "XX11"
            },
            "Title": {
                "DisplayValue": "M"
            },
            "FirstName": {
                "DisplayValue": "J"
            },
            "LastName": {
                "DisplayValue": "E"
            }
       }
    ]
}

我正在寻找一个设置或自定义转换器,将嵌套类折叠成各自的属性。

public string EmployeeId {get; set;} 

所以在上面的例子中赋值为:"XX11"

我已经玩了一段时间,现在我需要一些帮助。

这是支持开箱即用的还是你必须为它写一个自定义的转换器?

将嵌套类反序列化为基本属性类型

解决这个问题的一个可能的方法是编写一个JsonConverter,它在属性级别将"DisplayValue"对象压平到它的值。这实际上非常简单:

public class DisplayValueConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(string);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JObject obj = JObject.Load(reader);
        return (string)obj["DisplayValue"];
    }
    public override bool CanWrite
    {
        get { return false; }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

要使用转换器,您需要将[JsonConverter]属性添加到需要扁平化的Result类中的每个属性。

public class RootObject
{
    public bool isError { get; set; }
    public int Status { get; set; }
    public string Message { get; set; }
    public List<Result> Result { get; set; }
}
public class Result
{
    [JsonConverter(typeof(DisplayValueConverter))]
    public string EmployeeId { get; set; }
    [JsonConverter(typeof(DisplayValueConverter))]
    public string Title { get; set; }
    [JsonConverter(typeof(DisplayValueConverter))]
    public string FirstName { get; set; }
    [JsonConverter(typeof(DisplayValueConverter))]
    public string LastName { get; set; }
}

然后,将JSON反序列化到RootObject类中,它应该"刚刚工作":

RootObject root = JsonConvert.DeserializeObject<RootObject>(json);

演示小提琴:https://dotnetfiddle.net/0L9sjl

将json转换为class我得到了这个结构:

public class EmployeeId
    {
        public string DisplayValue { get; set; }
    }
    public class Title
    {
        public string DisplayValue { get; set; }
    }
    public class FirstName
    {
        public string DisplayValue { get; set; }
    }
    public class LastName
    {
        public string DisplayValue { get; set; }
    }
    public class Result
    {
        public EmployeeId EmployeeId { get; set; }
        public Title Title { get; set; }
        public FirstName FirstName { get; set; }
        public LastName LastName { get; set; }
    }
    public class RootObject
    {
        public bool isError { get; set; }
        public int Status { get; set; }
        public string Message { get; set; }
        public List<Result> Result { get; set; }
    }

要反序列化,可以使用

var res1 = JsonConvert.DeserializeObject<RootObject>(json); // Newton.json dll
           JavaScriptSerializer js = new JavaScriptSerializer(); // System.Web.Script.Serialization
           var res2 = js.Deserialize<RootObject>(json);