将 JSON 反序列化为嵌套 C# 类
下面是我在成功创建新的“工作代码”条目后从 REST API 获得的(稍微)精简的响应。我需要将响应反序列化到某些类中,但我很困惑。
作为参考,我在 .NET 3.5 中使用 JSON.NET(在 SQL Server 2008 R2 中的 SSIS 脚本中运行)来尝试反序列化。这是 JSON - 我显然无法控制它,因为它来自其他人的 API:
{
"results":{
"jobcodes":{
"1":{
"_status_code":200,
"_status_message":"Created",
"id":444444444,
"assigned_to_all":false,
"billable":true,
"active":true,
"type":"regular",
"name":"1234 Main Street - Jackson"
},
"2":{
"_status_code":200,
"_status_message":"Created",
"id":1234567890,
"assigned_to_all":false,
"billable":true,
"active":true,
"type":"regular",
"name":"4321 Some Other Street - Jackson"
}
}
}
}
在我的 C# 代码中,我确实定义了一个“JobCode”类,它仅将 JSON 值部分映射到属性 - 我对所有内容都不感兴趣返回给我的数据的数量:
[JsonObject]
class JobCode
{
[JsonProperty("_status_code")]
public string StatusCode { get; set; }
[JsonProperty("_status_message")]
public string StatusMessage { get; set; }
[JsonProperty("id")]
public string Id {get; set;}
[JsonProperty("name")]
public string Name { get; set; }
//-------------------------------------------------------------------------------
// Empty constructor for JSON serialization support
//-------------------------------------------------------------------------------
public JobCode() { }
}
我正在尝试通过此调用反序列化数据:
newResource = JsonConvert.DeserializeObject<JobCode>(jsonResponse);
其中 jsonResponse
是上面输出的代码。
当我执行代码时,“newResource”总是返回 null - 这并不意外,因为我知道数据中实际上有多个作业代码,并且此代码试图将其反序列化为单个 JobCode
对象。我尝试创建一个名为 JobCodes
的新类,如下所示:
class JobCodes
{
[JsonProperty("jobcodes")]
public List<JobCode>_JobCodes { get; set; }
}
然后我尝试调用它(JobCodes
而不是 JobCode
):
newResource = JsonConvert.DeserializeObject<JobCodes>(jsonResponse);
但是问题仍然存在 - 我的返回对象为空。 我认为让我失望的是“1”和“2”标识符的存在。我不知道如何解释它们在我的对象设计和/或 JSON.NET 类/属性属性(如 [JsonObject]
、[JsonProperty]
)的使用中的存在当
我通过 JSON2CSharp 运行 JSON 数据时,它构造了一些看起来很奇怪的类,因此并没有也证明了 有效的。我已经使用几个不同的验证器验证了 JSON,并且全部检查完毕 - 我只是不知道我在这里缺少什么。
最终,我想从 JSON 数据返回一个 List
,但我不知道需要做什么才能实现这一点。
Below is a (slightly) stripped down response I get from a REST API upon successful creation of a new "job code" entry. I need to deserialize the response into some classes, but I'm stumped.
For reference, I'm using JSON.NET in .NET 3.5 (running in a SSIS script in SQL Server 2008 R2) to attempt my deserialization. Here's the JSON - which I obviously have no control over as it's coming from someone else's API:
{
"results":{
"jobcodes":{
"1":{
"_status_code":200,
"_status_message":"Created",
"id":444444444,
"assigned_to_all":false,
"billable":true,
"active":true,
"type":"regular",
"name":"1234 Main Street - Jackson"
},
"2":{
"_status_code":200,
"_status_message":"Created",
"id":1234567890,
"assigned_to_all":false,
"billable":true,
"active":true,
"type":"regular",
"name":"4321 Some Other Street - Jackson"
}
}
}
}
In my C# code, I do have a "JobCode" class defined which only partially maps the JSON values to properties - I'm not interested in all of the data that's returned to me:
[JsonObject]
class JobCode
{
[JsonProperty("_status_code")]
public string StatusCode { get; set; }
[JsonProperty("_status_message")]
public string StatusMessage { get; set; }
[JsonProperty("id")]
public string Id {get; set;}
[JsonProperty("name")]
public string Name { get; set; }
//-------------------------------------------------------------------------------
// Empty constructor for JSON serialization support
//-------------------------------------------------------------------------------
public JobCode() { }
}
I'm attempting to deserialize the data via this call:
newResource = JsonConvert.DeserializeObject<JobCode>(jsonResponse);
Where jsonResponse
is the code outputted above.
When I execute the code, "newResource" always comes back as null - which is not unexpected because I know that there are actually multiple job codes in the data and this code is trying to deserialize it into a single JobCode
object. I tried creating a new class called JobCodes
that looks like this:
class JobCodes
{
[JsonProperty("jobcodes")]
public List<JobCode>_JobCodes { get; set; }
}
And then I tried calling this (JobCodes
instead of JobCode
):
newResource = JsonConvert.DeserializeObject<JobCodes>(jsonResponse);
But the issue persists - my return object is null.
What's throwing me off, I think, is the presence of the "1" and "2" identifiers. I don't know how to account for their presence in my object design and/or usage of the JSON.NET class / property attributes like [JsonObject]
,[JsonProperty]
, etc.
When I run the JSON data through JSON2CSharp, it constructs some weird-looking classes, so that hasn't proven too effective. I've validated the JSON with several different validators and it all checks out–I just don't know what I'm missing here.
Ultimately, I'd like to return a List<JobCode>
from the JSON data, but I'm stumped on what I need to do to make that happen.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的问题是双重的:
Dictionary
。普通的课程并不能解决这个问题;List
也不会。让你的类像这样:
然后,像这样反序列化:
这里的工作演示
Your problem is twofold:
Dictionary<string, T>
. A regular class won't work for that; neither will aList<T>
.Make your classes like this:
Then, deserialize like this:
Working demo here
因为您无法更改 JSON 的架构,并且无法设置常量属性数量,所以我建议您使用
JObject
警告:代码假设,JSON 始终处于正确的架构中。您还应该处理无效架构(例如,属性不属于
JobCode
架构)。Because you can't change the scheme of JSON, and you can't set constant No. of properties, I'd suggest you to use
JObject
Warning: code assumes, that JSON is always in proper schema. You should also handle invalid schema (for example where property is not of
JobCode
scheme).您还可以将 json 反序列化为目标类的对象,然后按照正常方式读取其属性:
其中 DeSerializeFromStrToObj 是一个自定义类,它利用反射来实例化目标类的对象:
完整的工作示例类可以在我对类似问题的增强回答中找到,此处
You can also deserialize your json to an object of your target class, and then read its properties as per normal:
where
DeSerializeFromStrToObj
is a custom class that makes use of reflection to instantiate an object of a targeted class:A complete working example class can be found in my enhanced answer to a similar question, here