C# - Json使用子属性反序列化对象

时间:2018-05-16 12:49:19

标签: c# json serialization attributes

我有以下json:

{
   "issue" : 
   {
      "id": 1,
      "project":
      {
         "id":1,
         "name":"name of project"
      }
   }
}

我试图将这个json反序列化为以下类:

public class Issue
{
    public int? id { get; set; }
    public int project_id { get; set; }
    public string project_name { get; set; }
}

Theres是一种获取子属性并设置为父亲的方法吗?

4 个答案:

答案 0 :(得分:1)

最简单的解决方案之一是转换为JObject并使用它从中创建所需的对象。

var jObject = JsonConvert.DeserializeObject<JObject>(text);

var issue = new Issue() {id = (int?)jObject["issue"]["id"], project_id = (int)jObject["issue"]["project"]["id"], project_name = (string)jObject["issue"]["project"]["name"]};

下面的代码提到了:

using System;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class Issue
{
    public int? id { get; set; }
    public int project_id { get; set; }
    public string project_name { get; set; }

    public override string ToString()
    {
        return "Id: " + id + " project Id: " + project_id + " project name : " + project_name;
    }
}


public class Program
{
    public static void Main()
    {
        var text = "{ \"issue\" :  { \"id\": 1, \"project\": { \"id\": 2, \"name\":\"name of project\" }}}";

        var jObject = JsonConvert.DeserializeObject<JObject>(text);

        var issue = new Issue() {id = (int?)jObject["issue"]["id"], project_id = (int)jObject["issue"]["project"]["id"], project_name = (string)jObject["issue"]["project"]["name"]};
        Console.WriteLine(issue);
    }
}

您可以在此处查看Live demo

答案 1 :(得分:0)

您需要为project

创建新的类

问题类:

public class Issue
{
    public int id { get; set; }
    public Project project { get; set; }
}

项目类:

public class Project
{
    public int id { get; set; }
    public String name { get; set; }
}

如果您确实需要在问题类中使用project_idproject_name,则可以执行以下操作:

public class Issue
{
    public int id { get; set; }
    public Project project { get; set; }

    public int getProjectId() {
        return this.getProject.getId;
    }
    //Do the same for projectName
}

希望得到这个帮助。

答案 2 :(得分:0)

Here是一种方法

这是代码

public class ConventionBasedConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return typeof(YOUR-OBJECT).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var daat = JObject.Load(reader);
        var yourObject = new YOUR-OBJECT();

        foreach (var prop in yourObject GetType().GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance))
        {
            var attr = prop.GetCustomAttributes(false).FirstOrDefault();
            if (attr != null)
            {
                var propName = ((JsonPropertyAttribute)attr).PropertyName;
                if (!string.IsNullOrWhiteSpace(propName))
                {
                    //split by the delimiter, and traverse recursevly according to the path
                    var conventions = propName.Split('/');
                    object propValue = null;
                    JToken token = null;
                    for (var i = 0; i < conventions.Length; i++)
                    {
                        if (token == null)
                        {
                            token = daat[conventions[i]];
                        }
                        else {
                            token = token[conventions[i]];
                        }
                        if (token == null)
                        {
                            //silent fail: exit the loop if the specified path was not found
                            break;
                        }
                        else
                        {
                            //store the current value
                            if (token is JValue)
                            {
                                propValue = ((JValue)token).Value;
                            }
                        }
                    }

                    if (propValue != null)
                    {
                        //workaround for numeric values being automatically created as Int64 (long) objects.
                        if (propValue is long && prop.PropertyType == typeof(Int32))
                        {
                            prop.SetValue(yourObject, Convert.ToInt32(propValue));
                        }
                        else
                        {
                            prop.SetValue(yourObject, propValue);
                        }
                    }
                }
            }
        }
        return yourObject;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
    }
}

然后使用它:

 var settings = new JsonSerializerSettings();
 settings.Converters.Add(new ConventionBasedConverter());
 JsonConvert.DeserializeObject<YOUR-OBJECT>(jsonString, settings);

答案 3 :(得分:0)

这是另一种方法。使用Cinchoo ETL - 一个开源库以及JSON路径,您可以使用几行代码进行反序列化

public class Issue
{
    [ChoJSONRecordField(JSONPath = "$..id")]
    public int? id { get; set; }
    [ChoJSONRecordField(JSONPath = "$..project.id")]
    public int project_id { get; set; }
    [ChoJSONRecordField(JSONPath = "$..project.name")]
    public string project_name { get; set; }
}

static void Sample33()
{
    string json = @"{
       ""issue"" : 
       {
          ""id"": 1,
          ""project"":
          {
             ""id"":1,
             ""name"":""name of project""
          }
       }
    }";
    var issue = ChoJSONReader<Issue>.LoadText(json).First();
}

免责声明:我是这个图书馆的作者。