繁体   English   中英

如何在C#中正确反序列化JSON

[英]How do I deserialize JSON correctly in C#

我正在尝试反序列化Supreme纽约JSON,但出现错误。

我使用json2csharp.com将Json转换为类。

然后我将它们全部归纳为一个称为items

namespace SUPBOTTESTING
{
    public class items
    {
        public string name { get; set; }
        public int id { get; set; }
        public string image_url { get; set; }
        public string image_url_hi { get; set; }
        public int price { get; set; }
        public int sale_price { get; set; }
        public bool new_item { get; set; }
        public int position { get; set; }
        public string category_name { get; set; }
        public int price_euro { get; set; }
        public int sale_price_euro { get; set; }
    }
}
using System;
using System.Net;
using System.Web.Script.Serialization;

namespace SUPBOTTESTING
{
    class Program
    {
        public static void Main()
        {
            {
                string shop_json = new WebClient().DownloadString("https://www.supremenewyork.com/mobile_stock.json");
                JavaScriptSerializer shop_object = new JavaScriptSerializer();
                items[] shirt_stock = shop_object.Deserialize<items[]>(shop_json);
                Console.WriteLine(shirt_stock[1]);

            }
        }
    }
}

我收到错误消息:

找不到类型SUPBOTTESTING.items []的默认构造函数

好了,您无需指定默认构造函数。 问题是,我认为您没有正确检查json数据。 因为您的items类不在json的第一级中。 您需要创建几个类才能在反序列化方面更加准确。

首先,您需要知道此json文件上有很多不良气味和不良做法。

请注意,您需要先安装Newtonsoft.Json然后再进行操作。 将json反序列化为C#类的方法更加方便。

但是,我写了一种反序列化的正确方法:

public class BaseItem
{

    public string Name { get; set; }
    public int Id { get; set; }
    public string Image_url { get; set; }
    public string Image_url_hi { get; set; }
    public int Price { get; set; }
    public int Sale_price { get; set; }
    public bool New_item { get; set; }
    public int Position { get; set; }
    public string Category_name { get; set; }
    public int Price_euro { get; set; }
    public int Sale_price_euro { get; set; }
}
public class Shirt : BaseItem { }
public class Bag : BaseItem { }
public class Accessory : BaseItem { }
public class Pant : BaseItem { }
public class Jacket : BaseItem { }
public class Skate : BaseItem { }
public class Hat : BaseItem { }
public class Sweatshirt : BaseItem { }
public class TopsSweater : BaseItem { }
public class New : BaseItem { }
public class RootObject
{
    public List<object> Unique_image_url_prefixes { get; set; }
    public ProductsAndCategories Products_and_categories { get; set; }
    public string Release_date { get; set; }
    public string Release_week { get; set; }
}
public class ProductsAndCategories
{
    public List<Shirt> Shirts { get; set; }
    public List<Bag> Bags { get; set; }
    public List<Accessory> Accessories { get; set; }
    public List<Pant> Pants { get; set; }
    public List<Jacket> Jackets { get; set; }
    public List<Skate> Skate { get; set; }
    public List<Hat> Hats { get; set; }
    public List<Sweatshirt> Sweatshirts { get; set; }
    [JsonProperty("Tops/Sweaters")]
    public List<TopsSweater> TopsSweaters { get; set; }
    public List<New> New { get; set; }
}

首先,所有项目的属性都相同,但是,它们都标记为不同的属性。 因此,我创建了一个BaseItem类以及从中继承的其他空类。

另外,您还需要其他2个类RootObjectProductsAndCategories来提供有关它们的数据。 请注意, TopsSweaters属性上有一个JsonProperty("blabla") 因为,在json文件中,它是Tops/Sweaters ,并且您不能在C#属性上使用该名称。 这是使用那种不同属性名称的属性。

然后,您可以像这样填充对象:

static void Main(string[] args)
    {
        var jsonData = "https://www.supremenewyork.com/mobile_stock.json";
        string shopJson = new WebClient().DownloadString(jsonData);
        RootObject shirtStock = JsonConvert.DeserializeObject<RootObject>(shopJson); //All json data is in this variable
        Console.WriteLine(shirtStock.Products_and_categories.Shirts[1]);
    }

好的,这是解决方案。 您有正确的想法,但需要了解Json数据的结构。

您将其deserializing化为Object数组,而返回的Json数据本身不是Array或List。 它包含作为数组的子节点,因此您需要相应地构造Object以获得成功的数据分解。

在这里,我已使用Newtonsoft将Json数据反序列化为对象。

我已经测试了代码,它返回了Shirts列表

static void Main(string[] args)
{
     var shop_json = new WebClient().DownloadString("https://www.supremenewyork.com/mobile_stock.json");
     var shirt_stock = JsonConvert.DeserializeObject<StockObject>(shop_json);

     // Picking shirts to demonstrate how to display values for all shirts
     var shirts = shirt_stock.products_and_categories.Shirts;
     foreach (var shirt in shirts)
     {
         var shirtBuilder = new StringBuilder();
         shirtBuilder.AppendLine($"Name: {shirt.name}");
         shirtBuilder.AppendLine($"ID: {shirt.id.ToString()}");
         shirtBuilder.AppendLine($"New Item: {shirt.new_item.ToString()}");
         shirtBuilder.AppendLine($"Category Name: {shirt.category_name}");
         Console.WriteLine(shirtBuilder);
     }
}
public class StockObject
{
    public ProductsCats Products_and_categories { get; set; }
}
public class ProductsCats
{
    public Details[] Shirts { get; set; }
    public Details[] Bags { get; set; }
    public Details[] Accessories { get; set; }
    public Details[] Pants { get; set; }
    public Details[] Jackets { get; set; }
    public Details[] Skates { get; set; }
    public Details[] Hats { get; set;}
    public Details[] Sweatshirts { get; set;}
    [JsonProperty("Tops/Sweaters")]
    public Details[] TopsSweaters { get;set;}
    public Details[] New { get; set; }
}
public class Details
{
    public string name { get; set; }
    public int id { get; set; }
    public string image_url { get; set; }
    public string image_url_hi { get; set; }
    public int price { get; set; }
    public int sale_price { get; set; }
    public bool new_item { get; set; }
    public int position { get; set; }
    public string category_name { get; set; }
    public int price_euro { get; set; }
    public int sale_price_euro { get; set; }
}

你看我在这里做什么?

因此,您的Json数据包含一个父节点products_and_categories ,其子节点包含一个Shirts数组,这是您想要的吗?

StockObject类包含类型为Products_and_categoriesParent属性,称为ProductsCats

ProductsCats对象包含属性Shirts型的Details这是一个数组,将在可以使用deserialising过程。

希望这可以帮助?

您的问题是您使用类来加载JSON数据,您应该在其中使用结构,或者您也可以创建不带参数的构造函数,并将所有变量设置为默认值,这是很多工作,因此只需替换带有struct class

public struct Items
{
    public string Name { get; set; }
    public int Id { get; set; }
    public string Image_Url { get; set; }
    public string Image_Url_Hi { get; set; }
    public int Price { get; set; }
    public int Sale_Price { get; set; }
    public bool New_item { get; set; }
    public int Position { get; set; }
    public string Category_Name { get; set; }
    public int Price_Euro { get; set; }
    public int Sale_Price_Euro { get; set; }
}

另外,请遵守C#命名约定,因为大多数JSON解析器默认情况下都不区分大小写,因此您应该能够执行此操作。

更多信息:如果您没有定义一个类,则该类实际上并没有适当的默认构造函数,因为结构始终具有一个默认构造函数,因此,当JSON解析器要初始化您的类时,它将无法启动,因为未定义默认构造函数。

 static void Main(string[] args)
    {
        string shop_json = new WebClient().DownloadString("https://www.supremenewyork.com/mobile_stock.json");

        JavaScriptSerializer shop_object = new JavaScriptSerializer();
        var shirt_stock = shop_object.Deserialize<NewYarkItems>(shop_json);

        var v = shirt_stock;

    }


public class NewYarkItems
{
    public dynamic unique_image_url_prefixes { get; set; }
    public products_and_categories products_And_Categories { get; set; }
    public string release_date { get; set; }
    public string release_week { get; set; }
}

public class products_and_categories
{
    public List<items> Jackets { get; set; }
}


public class items
{
    public string name { get; set; }
    public int id { get; set; }
    public string image_url { get; set; }
    public string image_url_hi { get; set; }
    public int price { get; set; }
    public int sale_price { get; set; }
    public bool new_item { get; set; }
    public int position { get; set; }
    public string category_name { get; set; }
    public int price_euro { get; set; }
    public int sale_price_euro { get; set; }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM