C # - Json десериализует объект с дочерними атрибутами - PullRequest
0 голосов
/ 16 мая 2018

У меня есть следующий 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; }
}

Есть способ получить атрибут child и установить его для отца?

Ответы [ 4 ]

0 голосов
/ 16 мая 2018

Вот еще один способ сделать это.С 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();
}

Отказ от ответственности: я являюсь автором этой библиотеки.

0 голосов
/ 16 мая 2018

Здесь - способ сделать это

А вот и код

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);
0 голосов
/ 16 мая 2018

Одним из самых простых решений является преобразование в 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 здесь.

0 голосов
/ 16 мая 2018

Вам необходимо создать новый класс для 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_id и project_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
}

Надеюсь, эта помощь.

...