Deserialize json based on fields in .Net (C#)

后端 未结 5 598
余生分开走
余生分开走 2021-02-09 12:05

I\'m writing an app that gets a Json list of objects like this:

[
   {
       \"ObjectType\": \"apple\",
       \"ObjectSize\": 35,
       \"ObjectC         


        
相关标签:
5条回答
  • 2021-02-09 12:25

    This is not an answer but in C# 6.0 you will be able to do this:

      using Microsoft.VisualStudio.TestTools.UnitTesting;
      using Newtonsoft.Json.Linq;
      [TestMethod]
      public void JsonWithDollarOperatorStringIndexers()
      {
    
          // Additional data types eliminated for elucidation
          string jsonText = @"
            {
              'Byte':  {
                'Keyword':  'byte',
                'DotNetClassName':  'Byte',
                'Description':  'Unsigned integer',
                'Width':  '8',
                'Range':  '0 to 255'
                        },
              'Boolean':  {
                'Keyword':  'bool',
                'DotNetClassName':  'Boolean',
                'Description':  'Logical Boolean type',
                'Width':  '8',
                'Range':  'True or false.'
                          },
            }";
          JObject jObject = JObject.Parse(jsonText);
          Assert.AreEqual("bool", jObject.$Boolean.$Keyword);
        }
    

    Taken from here.

    0 讨论(0)
  • 2021-02-09 12:28

    Take a look at newtonsoft's JSON library

    With it you can do stuff like:

    ...
    public class Movie
    {
       public string Name;
       public DateTime ReleaseDate;
       public string[] Genres;
    }
    ......
    
    string json = @"{
      'Name': 'Bad Boys',
      'ReleaseDate': '1995-4-7T00:00:00',
      'Genres': [
        'Action',
        'Comedy'
      ]
    }";
    
    Movie m = JsonConvert.DeserializeObject<Movie>(json);
    
    string name = m.Name;
    // Bad Boys
    
    0 讨论(0)
  • 2021-02-09 12:32

    Some time ago I had the same problem.

    You'll can use Json.NET, but if you don't have control over the json document (as in: 'it has been serialized by some other framework') you'll need to create a custom JsonConverter like this:

    class MyItemConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return typeof(ItemToSell).IsAssignableFrom(objectType);
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JObject obj = JObject.Load(reader);
            string discriminator = (string)obj["ObjectType"];
    
            ItemToSell item;
            switch (discriminator)
            {
                case "apple":
                    item = new Apple();
                    break;
                case "books":
                    item = new Books();
                    break;
                case "melon":
                    item = new Melon();
                    break;
                default:
                    throw new NotImplementedException();
            }
    
            serializer.Populate(obj.CreateReader(), item);
    
            return item;
    
        }
    
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
    
        }
    }
    

    Then you'll need to add it to the converters of the JsonSerializerSettings like so:

    JsonSerializerSettings settings = new JsonSerializerSettings
    {
        TypeNameHandling = TypeNameHandling.Objects,
    
    };
    settings.Converters.Add(new MyItemConverter());
    var items = JsonConvert.DeserializeObject<List<ItemToSell>>(response, settings);
    
    0 讨论(0)
  • 2021-02-09 12:43

    Define base class and derived classes.

    the use [JSON.net](also available via NuGet)1 to deserialize them.

    I.e.

    class ItemToSell {
     string Type {get;set;}
     string Size {get;set;}
     string Cost {get;set;}
    }
    
    class Book : ItemToSell { ...}
    

    Then deserialize using

    var catalog = JsonConvert.Deserialize<List<ItemToSell>>(json);
    

    The deserializer will ignore unexpected properties. Call it again using a specific type to get other properties if you need.

    0 讨论(0)
  • 2021-02-09 12:46

    You can use a CustomCreationConverter. This lets you hook into the deserialization process.

    public abstract class Base
    {
        public string Type { get; set; }
    }
    
    class Foo : Base
    {
        public string FooProperty { get; set; }
    }
    
    class Bar : Base
    {
        public string BarProperty { get; set; }
    }
    
    class CustomSerializableConverter : CustomCreationConverter<Base>
    {
        public override Base Create(Type objectType)
        {
            throw new NotImplementedException();
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            var jObject = JObject.Load(reader);
    
            var type = (string)jObject.Property("Type");
            Base target;
            switch (type)
            {
                case "Foo":
                    target = new Foo();
                    break;
                case "Bar":
                    target = new Bar();
                    break;
                default:
                    throw new InvalidOperationException();
            }
            serializer.Populate(jObject.CreateReader(), target);
            return target;
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            var json = "[{Type:\"Foo\",FooProperty:\"A\"},{Type:\"Bar\",BarProperty:\"B\"}]";
            List<Base> bases = JsonConvert.DeserializeObject<List<Base>>(json, new CustomSerializableConverter());
        }
    }
    
    0 讨论(0)
提交回复
热议问题