【问题标题】:How to convert this json into C# object如何将此 json 转换为 C# 对象
【发布时间】:2018-02-27 19:01:56
【问题描述】:

我从第三方收到此 JSON,因此无法控制它,

{
    code: 200,
    message: success,
    data: {
        categories: {
            0: {
                prop1: 100,
                prop2: blah
            },
            1: {
                prop1: 100,
                prop2: blah
            }
                    // etc.. etc.. it may return around 100 or more categories or less
        }
    }
}

现在我正在尝试将其转换为 C# 对象,

[DataContract]
public class Category
{
    [DataMember] public string prop1 { get; set; }
    [DataMember] public string prop2 { get; set; }
}

[DataContract]
public class Data
{
    [DataMember]
    public List<Category> categories { get; set; }
}

[DataContract]
public class RootObject
{
    [DataMember]
    public int code { get; set; }
    [DataMember]
    public string message { get; set; }
    [DataMember]
    public Data data { get; set; }
}

以及转换它的代码,

   var response = LoadPageAsync(url).Result;
   var serializer = new JavaScriptSerializer();
   var rootObject = serializer.Deserialize<RootObject>(response);

问题是我将类别计数归零,即使 JSON 它本身有很多。

【问题讨论】:

  • 有什么特别的原因您使用的是 JavascriptSerializer 而不是 Json.NET?
  • @Bejasc 我是序列化新手,但我愿意接受任何更好的解决方案 :)
  • NewtonSoft.Json 几乎是 C# 中序列化的事实标准。
  • 显然您使用的是DataContractJSONSerializer 而不是JavascriptSerializer
  • json 中的类别不是一个数组,它只是两个对象“0”和“1”,但反序列化器希望您的代码中有一个列表

标签: javascript c# json


【解决方案1】:

在这里你可以找到很多方法来做你想做的事,我个人喜欢 JavaScriptJsonSerializer。 enter link description here

使用 JavaScriptJsonSerializer

JavaScriptSerializer 是一个有助于序列化和反序列化 JSON 的类。它存在于程序集 System.Web.Extensions.dll 中可用的命名空间 System.Web.Script.Serialization 中。要将 .Net 对象序列化为 JSON 字符串,请使用 Serialize 方法。可以使用 Deserialize 或 DeserializeObject 方法将 JSON 字符串反序列化为 .Net 对象。让我们看看如何使用 JavaScriptSerializer 实现序列化和反序列化。

下面的代码 sn-p 是声明 BlogSites 类型的自定义类。

class BlogSites  
{  
    public string Name { get; set; }  
    public string Description { get; set; }  
}  

序列化

在序列化中,它将自定义 .Net 对象转换为 JSON 字符串。在下面的代码中,它创建了一个 BlogSiteclass 的实例,并为其属性分配了一些值。然后我们创建一个 JavaScriptSerializer 实例,并通过传递 object(BlogSites) 调用 Serialize() 方法。它以字符串格式返回 JSON 数据。

// Creating BlogSites object  
BlogSites bsObj = new BlogSites()  
{  
   Name = "C-sharpcorner",  
   Description = "Share Knowledge"  
};  



// Serializing object to json data  
JavaScriptSerializer js = new JavaScriptSerializer();  
string jsonData = js.Serialize(bsObj); // {"Name":"C-sharpcorner","Description":"Share Knowledge"} 

反序列化

在反序列化中,它与序列化相反,这意味着它将 JSON 字符串转换为自定义的 .Net 对象。在以下代码中,它创建 JavaScriptSerializer 实例并通过传递 JSON 数据调用 Deserialize()。它从 JSON 数据返回自定义对象 (BlogSites)。

// Deserializing json data to object  
JavaScriptSerializer js = new JavaScriptSerializer();  
BlogSites blogObject = js.Deserialize<BlogSites>(jsonData);  
string name = blogObject.Name;  
string description = blogObject.Description;




// Other way to whithout help of BlogSites class  
dynamic blogObject = js.Deserialize<dynamic>(jsonData);  
string name = blogObject["Name"];  
string description = blogObject["Description"];  

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
  • @derape 谢谢你的建议。我在编辑中这样做了
【解决方案2】:

使用 Json.NET

public class Category
{
    public string prop1;
    public string prop2;
}

public class Data
{
    public List<Category> categories;
}

public class RootObject
{
    public int code;
    public string message;
    public Data data;
}

删除DataContract 代码以制作简单的类结构。

使用 JSON.Net 反序列化对象

RootObject data = JsonConvert.DeserializeObject<RootObject>(jsonString);

RootObject 是您的顶级对象。

然后您应该能够像访问任何普通对象一样访问它,即

string firstProp1 = RootObject.data.categories[0].prop1

【讨论】:

  • 这将无法反序列化,因为类别不是一个简单的数组,而是一个包含更多对象的对象。
  • @StephenVernyi 您仍然可以像访问数组一样访问列表中的索引。编辑:对不起,我误解了你的意思。
  • 但是Newtonsoft会抛出一个错误,因为它不能正确反序列化。
  • 误解了你原来的评论,道歉。
  • 一切都好。 Json 的细微变化需要完全不同的类结构。有时很烦人
【解决方案3】:

使用Json.NET

将 Json 反序列化为对象变得如此简单:

string json = @"{
  'Email': 'james@example.com',
  'Active': true,
  'CreatedDate': '2013-01-20T00:00:00Z',
  'Roles': [
    'User',
    'Admin'
  ]
}";

Account account = JsonConvert.DeserializeObject<Account>(json);

Console.WriteLine(account.Email);
// james@example.com

作为自己的docs表演。

Json.NET 会将任何 Json 转换为对象,只要您在代码中定义了它。 Account 在这种情况下可以是任何东西,RootObject 在你的情况下。如果您的 Json 的某些内容不符合标准,它也可能会返回一些有用的异常。

【讨论】:

  • 真的吗?这就是答案?
  • @r41n 我的 JSON 和你的不一样,我不能这样做
  • @Mathematics,Json 没关系,Json.NET 会将任何 Json 转换为对象,只要您在代码中定义了它。 Account 在这种情况下可以是任何东西,RootObject 在你的情况下。
  • 此处显示的 Json 取自 Json.NET 示例代码。
【解决方案4】:

您需要将类别列表更改为字典。测试了以下代码,我根据需要实现了反序列化。还值得注意的是,您的 json 实际上是 invalid ,字符串周围没有引号。我也使用了 JSON.Net,但这应该是无关紧要的。

[DataContract]
public class Category
{
    [DataMember] public string prop1 { get; set; }
    [DataMember] public string prop2 { get; set; }
}

[DataContract]
public class Data
{
    [DataMember]
    public Dictionary<int, Category> categories { get; set; }
}

[DataContract]
public class RootObject
{
    [DataMember]
    public int code { get; set; }
    [DataMember]
    public string message { get; set; }
    [DataMember]
    public Data data { get; set; }
}

static void Main(string[] args)
{
    var root = new RootObject()
    {
        code = 1,
        message = "test",
        data = new Data()
        {
            categories = new Dictionary<int, Category>()
            {
                { 0, new Category()
                    {
                        prop1 = "cat1prop1",
                        prop2 = "cat1prop2"
                    }
                },
                { 1,  new Category()
                    {
                        prop1 = "cat2prop1",
                        prop2 = "cat2prop2"
                    }
                }
            }
        }
    };
    var testJson = "{code: 200,message: \"success\",data: {categories: {0: {prop1: 100,prop2: \"blah\"},1: {prop1: 100,prop2: \"blah\"}}}}";
    var json = JsonConvert.SerializeObject(root);
    var testConvert = JsonConvert.DeserializeObject<RootObject>(testJson);
}

【讨论】:

    【解决方案5】:

    json 无效,字符串需要用" 括起来。

    你可以在这里测试你的json

    https://jsonlint.com/

    这是有效的:

    {
        "code": 200,
        "message": "success",
        "data": {
            "categories": {
                "0": {
                    "prop1": 100,
                    "prop2": "blah"
                },
                "1": {
                    "prop1": 100,
                    "prop2": "blah"
                }
            }
        }
    }
    

    型号:

    public class Zero
        {
    
            [JsonProperty("prop1")]
            public int Prop1 { get; set; }
    
            [JsonProperty("prop2")]
            public string Prop2 { get; set; }
        }
    
        public class One
        {
    
            [JsonProperty("prop1")]
            public int Prop1 { get; set; }
    
            [JsonProperty("prop2")]
            public string Prop2 { get; set; }
        }
    
        public class Categories
        {
    
            [JsonProperty("0")]
            public Zero Zero { get; set; }
    
            [JsonProperty("1")]
            public One One { get; set; }
        }
    
        public class Data
        {
    
            [JsonProperty("categories")]
            public Categories Categories { get; set; }
        }
    
        public class Example
        {
    
            [JsonProperty("code")]
            public int Code { get; set; }
    
            [JsonProperty("message")]
            public string Message { get; set; }
    
            [JsonProperty("data")]
            public Data Data { get; set; }
        }
    

    使用 Newtonsoft Json:

    var example = Newtonsoft.Json.JsonConvert.DeserializeObject<Example>(json);
    

    【讨论】:

    • 请重新阅读问题。它声明它来自第三方来源,并且无法控制 json 格式。
    • @Bejasc json 按原样无效,因此除非将其设为有效,否则无法反序列化......缺少编写自己的反序列化程序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2015-02-05
    • 1970-01-01
    • 2016-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多