Newtonsoft. JSON источник условного свойства - PullRequest
1 голос
/ 02 апреля 2020

Я использую Newtonsoft JSON для сериализации и десериализации. У меня есть json, представляющий поля, где свойство title представляет отображаемое имя:

{
  "ID": {
    "type": "integer",
    "title": "ID Display Name"
  },
  "TITLE": {
    "type": "string",
    "title": "Title Display name"
  },
  "NAME": {
    "type": "string",
    "title": "Name"
  },
  "CUSTOM_123": {
    "type": "string",
    "title": "CUSTOM_123",
    "formLabel": "CUSTOM_123 Display Name"
  }
  // ... etc
}

И у меня есть класс:

public class Field
{
    public string Title { get; set; }
    public string Type { get; set; }
}

Теперь все работает нормально. Но когда имя поля начинается с "CUSTOM_", мне нужно сериализовать "Title" из свойства "formLabel".

Как реализовать источник условных свойств?

Ответы [ 3 ]

1 голос
/ 02 апреля 2020

Вы можете проанализировать JSON в JObject, затем перечислить все свойства, десериализовать их один за другим в Field экземпляр и обновить значение Title, если имя свойства в JSON начинается с CUSTOM_ строка

var json = JObject.Parse(jsonString);

foreach (var property in json.Properties())
{
    var field = property.Value.ToObject<Field>();
    if (property.Name.StartsWith("CUSTOM_")&&property.Value is JObject propertyObject)
    {
        field.Title = propertyObject["formLabel"]?.Value<string>();
    }
}

Этот подход проще, чем, на мой взгляд, написание собственного конвертера

0 голосов
/ 02 апреля 2020

Наличие вашего пользовательского JsonConverter поможет вам, так что вы разделите бизнес десериализации и сможете включить больше бизнеса, как требуется в методе преобразования. поэтому в первых строках ньютон софт сериализует обычно наш объект в поле, а затем настраивает бизнес для «Custom _», работающую скрипку https://dotnetfiddle.net/aVpB8I

Код, как показано ниже:

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;

namespace testapp
{
    class Program
    {
        static void Main(string[] args)
        {
            string json = @"
        {
            ""ID"": {
                ""type"": ""integer"",
                ""title"": ""ID Display Name""
            },
            ""TITLE"": {
                ""type"": ""string"",
                ""title"": ""Title Display name""
            },
            ""NAME"": {
                ""type"": ""string"",
                ""title"": ""Name""
            },
            ""CUSTOM_123"": {
                ""type"": ""string"",
                ""title"": ""CUSTOM_123"",
                ""formLabel"": ""CUSTOM_123 Display Name""
            }
        }";
            List<Field> result = JsonConvert.DeserializeObject<List<Field>>(json, new JobInfoConverter());
        }



        public class Field
        {
            public string title { get; set; }
            public string type { get; set; }
        }

        public class JobInfoConverter : JsonConverter
        {
            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                try
                {
                    List<Field> result = new List<Field>();
                    var content = JObject.Load(reader);
                    foreach (var prop in content.Properties())
                    {
                        var parsedValue = prop.Value.ToObject<Field>();
                        if (prop.Name.StartsWith("CUSTOM_"))
                        {
                            parsedValue.title = prop.Value["formLabel"].ToString();
                        }
                        result.Add(parsedValue);

                    }
                    return result;
                }
                catch (Exception ex)
                {
                    return null;
                }
            }

            public override void WriteJson(JsonWriter writer, object value, Newtonsoft.Json.JsonSerializer serializer) => throw new NotImplementedException();

            public override bool CanConvert(Type objectType)
            {
                return true;
            }

            public override bool CanWrite => true;

        }
    }

}

0 голосов
/ 02 апреля 2020

Вы можете десериализовать объект, используя Newtonsoft с пользовательской JsonConverter.

Ваша структура JSON представляет собой объект JSON, который содержит несколько дочерних JSON объектов (полей). Поэтому при десериализации его до. NET вы можете создать отдельный класс для parent, который будет иметь список Fields. Вы также можете изменить JSON на массив вместо объекта и десериализовать до List<Fields>.

IList<Field> fields = JsonConvert.DeserializeObject<IList<Field>>(json, new CustomJsonConverter());
public class CustomJsonConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        IList<Field> fields = new List<Field>();
        JObject obj = JObject.Load(reader);
        foreach (JToken child in obj.Children())
        {
            Field field = new Field();
            JProperty fieldProp = (JProperty)child;
            JObject fieldValue = (JObject)fieldProp.Value;
            string fieldName = fieldProp.Name;
            if (fieldName .StartsWith("CUSTOM_"))
            {
                field.Title = (string)fieldValue["formLabel"];
                field.Type = (string)fieldValue["type"];
            }
            else
            {
                field.Title = (string)fieldValue["title"];
                field.Type = (string)fieldValue["type"];
            }

            fields.Add(field);
        }

        return fields;
    }


    public override bool CanConvert(Type objectType)
    {
        return true;
    }
}
public class Field
{
    public string Title { get; set; }

    public string Type{ get; set; }
}

https://dotnetfiddle.net/5bNihC

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...