Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于.Net(C#)中的字段反序列化json_C#_.net_Json_Field_Deserialization - Fatal编程技术网

基于.Net(C#)中的字段反序列化json

基于.Net(C#)中的字段反序列化json,c#,.net,json,field,deserialization,C#,.net,Json,Field,Deserialization,我正在编写一个应用程序,它将获得一个对象列表,如下所示: [ { "ObjectType": "apple", "ObjectSize": 35, "ObjectCost": 4, "ObjectTaste": "good", "ObjectColor": "golden" }, { "ObjectType": "books", "ObjectSize": 53, "

我正在编写一个应用程序,它将获得一个对象列表,如下所示:

[
   {
       "ObjectType": "apple",
       "ObjectSize": 35,
       "ObjectCost": 4,
       "ObjectTaste": "good",
       "ObjectColor": "golden"
   },
   {
       "ObjectType": "books",
       "ObjectSize": 53,
       "ObjectCost": 7,
       "Pages": 100
   },
   {
       "ObjectType": "melon",
       "ObjectSize": 35,
       "ObjectTaste": "good",
       "ObjectCost": 5
   },
   {
       "ObjectType": "apple",
       "ObjectSize": 29,
       "ObjectCost": 8,
       "ObjectTaste": "almost good",
       "ObjectColor": "red"
   }
  ]
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)
    {

    }
}
我想创建一个基类
ItemToSell
(size,cost),并从中派生Apple、甜瓜和Book,然后根据“
ObjectType
”字段将其反序列化为适合的任何类。我想让它建立一个
ItemToSell
对象列表,每个对象都是苹果、甜瓜或书

我怎样才能在.Net中做到这一点

提前感谢:)

编辑:我知道如何在一个包含所有字段的大类中反序列化它,比如:
Base(ObjectType、ObjectSize、ObjectCost、ObjectColor、Pages)
。但是我想让它通过
ObjectType
来区分类,这样我就不会有任何有用的字段,比如每本书的Pages字段或者每本书的
ObjectTaste

有了它,你可以做以下事情:

...
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
。。。
公映
{
公共字符串名称;
公共日期时间发布日期;
公共字符串[]类型;
}
......
字符串json=@”{
“名字”:“坏男孩”,
“发布日期”:“1995-4-7T00:00:00”,
“流派”:[
“行动”,
“喜剧”
]
}";
Movie m=JsonConvert.DeserializeObject(json);
字符串名称=m.名称;
//坏小子

定义基类和派生类

使用[JSON.net](也可通过NuGet获得)对它们进行反序列化

然后使用

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

反序列化程序将忽略意外属性。如果需要,请使用特定类型再次调用它以获取其他属性。

不久前,我遇到了同样的问题

您可以使用Json.NET,但如果您无法控制Json文档(如:“它已被其他框架序列化”),则需要创建一个自定义JsonConverter,如下所示:

[
   {
       "ObjectType": "apple",
       "ObjectSize": 35,
       "ObjectCost": 4,
       "ObjectTaste": "good",
       "ObjectColor": "golden"
   },
   {
       "ObjectType": "books",
       "ObjectSize": 53,
       "ObjectCost": 7,
       "Pages": 100
   },
   {
       "ObjectType": "melon",
       "ObjectSize": 35,
       "ObjectTaste": "good",
       "ObjectCost": 5
   },
   {
       "ObjectType": "apple",
       "ObjectSize": 29,
       "ObjectCost": 8,
       "ObjectTaste": "almost good",
       "ObjectColor": "red"
   }
  ]
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)
    {

    }
}
然后需要将其添加到JsonSerializerSettings的转换器中,如下所示:

JsonSerializerSettings settings = new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.Objects,

};
settings.Converters.Add(new MyItemConverter());
var items = JsonConvert.DeserializeObject<List<ItemToSell>>(response, settings);
JsonSerializerSettings设置=新的JsonSerializerSettings
{
TypeNameHandling=TypeNameHandling.Objects,
};
添加(新的MyItemConverter());
var items=JsonConvert.DeserializeObject(响应、设置);

这不是答案,但在C#6.0中,您可以做到:

  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);
    }
摘自

您可以使用。这使您能够钩住反序列化过程

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());
    }
}
公共抽象类基类
{
公共字符串类型{get;set;}
}
Foo类:Base
{
公共字符串属性{get;set;}
}
类别栏:基本
{
公共字符串属性{get;set;}
}
类CustomSerializableConverter:CustomCreationConverter
{
公共重写基创建(类型objectType)
{
抛出新的NotImplementedException();
}
公共重写对象ReadJson(JsonReader阅读器,类型objectType,对象existingValue,JsonSerializer序列化程序)
{
var jObject=jObject.Load(读卡器);
变量类型=(字符串)jObject.Property(“类型”);
基本目标;
开关(类型)
{
案例“Foo”:
target=newfoo();
打破
案例“酒吧”:
目标=新条();
打破
违约:
抛出新的InvalidOperationException();
}
填充(jObject.CreateReader(),目标);
回报目标;
}
}
班级计划
{
静态void Main(字符串[]参数)
{
var json=“[{Type:\'Foo\',FooProperty:\'A\'},{Type:\'Bar\',BarProperty:\'B\'}]”;
List base=JsonConvert.DeserializeObject(json,新的CustomSerializableConverter());
}
}

它不是有效的json,请确保它是完整的jsonOk我知道如何从json转换到c#类并反序列化对象,但我希望它基于ObjectType在列表中创建对象。不过还是要谢谢你的回答。