将包含对象属性的JSON API结果Map(反序列化)为编号列表

3lxsmp7m  于 2023-05-19  发布在  其他
关注(0)|答案(2)|浏览(170)

我在SO和谷歌上搜索过类似的问题,但找不到我要搜索的确切内容。
我正在开发一个应用程序,它查询一个API,返回以下结果:

{
    "Ticket": {
        "1": {
            "DisplayName": "Ticket ID",
            "Value": 117
        },
        "2": {
            "DisplayName": "Last Modified",
            "Value": "2022-10-05T18:09:32.1070000Z"
        },
        "3": {
            "DisplayName": "Last User",
            "Value": "SYSTEMACCOUNT"
        },
        "4": {
            "DisplayName": "Seq_Group",
            "Value": 1
        },
        ...
    }
}

我想把它反序列化为一个对象,如下所示:

public class Ticket 
{
    public property int TicketID {get; set;}
    public property DateTime LastModified {get; set;}
    public property string LastUser {get; set;}
    public property int Seq_Group {get; set;}
}

(为了简洁起见,这里还隐藏了几个属性)
你能给我指出如何以最佳方式进行Map的方向吗?
我知道我可以将它反序列化为一个字典,然后用几个if和elses迭代字典,但我认为一定有更聪明的方法来解决这个问题。
谢谢!

h43kikqp

h43kikqp1#

你只需要一行代码

Ticket ticket =  new JObject( ((JObject)JObject.Parse(json)["Ticket"]).Properties()
      .Select(t=> new JProperty((string) t.Value["DisplayName"], t.Value["Value"])))
      .ToObject<Ticket>();

把你的课改好

public class Ticket
{
    [JsonProperty("Ticket ID")]
    public int TicketID { get; set; }
    
    [JsonProperty("Last Modified")]
    public DateTime LastModified { get; set; }
    
    [JsonProperty("Last User")]
    public string LastUser { get; set; }
    
    public int Seq_Group { get; set; }
}
a8jjtwal

a8jjtwal2#

您可以使用JsonConstructorAttribute和 * System.Reflection * 进行属性Map。
1.使用[DisplayName]属性定义应从JSONMap哪个属性名。

using System.ComponentModel; 

public class Ticket 
{
    [DisplayName("Ticket ID")]
    public int TicketID {get; set;}
    [DisplayName("Last Modified")]
    public DateTime LastModified {get; set;}
    [DisplayName("Last User")]
    public string LastUser {get; set;}
    public int Seq_Group {get; set;}    
}

1.从[DisplayName]属性(如果应用)或其默认属性名检索属性名的扩展方法。

using System.ComponentModel; 
using System.Reflection;

public static class ReflectionExtensions
{
    public static string ToName(this PropertyInfo propertyInfo)
    {
        try
        {
            object[] displayNameAttributes = propertyInfo
                .GetCustomAttributes(typeof(DisplayNameAttribute), false)
                .ToArray();

            if (displayNameAttributes != null && displayNameAttributes.Count() > 0)
                return ((DisplayNameAttribute)displayNameAttributes[0]).DisplayName;

            return propertyInfo.Name;
        }
        catch
        {
            return propertyInfo.Name;
        }
    }
}

1.通过应用[JsonConstructor]属性在构造函数中实现转换逻辑。

using System.ComponentModel; 
using System.Reflection;
using Newtonsoft.Json.Linq;
using System.Globalization;

public class Root
{
    public Ticket Ticket { get; set; }
    
    [JsonConstructor]
    public Root(Dictionary<string, JObject> ticket)
    {
        Ticket = new Ticket();
        
        foreach (KeyValuePair<string, JObject> kvp in ticket)
        {
            string propertyName = kvp.Value.SelectToken("DisplayName").ToString();
            
            PropertyInfo propInfo = typeof(Ticket).GetProperties().FirstOrDefault(x => x.ToName() == propertyName);
            if (propInfo != null)
            {
                JToken value = kvp.Value.SelectToken("Value");
                
                Type propType = propInfo.PropertyType;
                if (propType == typeof(DateTime))
                    propInfo.SetValue(Ticket, DateTime.Parse(value.ToString()));                
                else
                    propInfo.SetValue(Ticket, value.ToObject(propType));
            }
        }
    }
}

Demo @ .NET Fiddle

相关问题