1
votes

Source de propriété conditionnelle Newtonsoft.JSON

J'utilise Newtonsoft JSON pour la sérialisation et la désérialisation. J'ai json représentant des champs où la propriété title représente un nom d'affichage:

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

Et j'ai la classe:

{
  "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
}

Maintenant, tout fonctionne bien. Mais lorsque le nom du champ commence par "CUSTOM_", je dois sérialiser "Title" à partir de la propriété "formLabel".

Comment pourrais-je implémenter une source de propriété conditionnelle?


1 commentaires

Que se passe-t-il si le titre et fromLable sont fournis?


3 Réponses :



0
votes

Vous pouvez désérialiser en objet en utilisant Newtonsoft avec JsonConverter personnalisé.

Votre structure JSON est un objet JSON, qui contient plusieurs objets JSON enfants (champs). Ainsi, lors de la désérialisation en .NET, vous pouvez créer une classe distincte pour le parent qui aura une liste de Champs . Vous pouvez également changer votre JSON en tableau au lieu d'objet et désérialiser en List.

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

    public string Type{ get; set; }
}
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;
    }
}
IList<Field> fields = JsonConvert.DeserializeObject<IList<Field>>(json, new CustomJsonConverter());

https://dotnetfiddle.net/5bNihC


0 commentaires

0
votes

Avoir votre JsonConverter personnalisé fera l'affaire, vous séparerez donc les activités de désérialisation et vous pourrez inclure plus d'affaires selon les besoins dans la méthode de conversion. donc dans les premières lignes newton soft sérialise normalement notre objet à Field puis pour avoir le business personnalisé pour "Custom _", en travaillant le violon https: / /dotnetfiddle.net/aVpB8I

Code comme ci-dessous:

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 commentaires