C# 如何使用JSON.NET反序列化JSON对象的一部分

C# 如何使用JSON.NET反序列化JSON对象的一部分,c#,json,asp.net-mvc,asp.net-mvc-5,json.net,C#,Json,Asp.net Mvc,Asp.net Mvc 5,Json.net,我正在开发一个asp.net mvc web应用程序。我正在接收以下json对象:- { "operation":{ "name":"GET RESOURCE ACCOUNTLIST", "result":{ "status":"Success", "message":"Resource details with account list fetched successfully" }, "De

我正在开发一个asp.net mvc web应用程序。我正在接收以下json对象:-

{  
   "operation":{  
      "name":"GET RESOURCE ACCOUNTLIST",
      "result":{  
         "status":"Success",
         "message":"Resource details with account list fetched successfully"
      },
      "Details":{  
         "RESOURCE ID":"1",
         "RESOURCE NAME":"test resource",
         "RESOURCE DESCRIPTION":"",
         "RESOURCE TYPE":"Windows",
         "DNS NAME":"172.16.20.101",
         "PASSWORD POLICY":"Strong",
         "DEPARTMENT":"",
         "LOCATION":"",
         "RESOURCE URL":"",
         "RESOURCE OWNER":"admin",
         "ACCOUNT LIST":[  
            {  
               "ISFAVPASS":"false",
               "ACCOUNT NAME":"root",
               "PASSWDID":"1",
               "IS_TICKETID_REQD_MANDATORY":"false",
               "ISREASONREQUIRED":"false",
               "AUTOLOGONLIST":[  
                  "Windows Remote Desktop",
                  "Remote Desktop"
               ],
               "PASSWORD STATUS":"****",
               "IS_TICKETID_REQD":"false",
               "ACCOUNT ID":"1",
               "AUTOLOGONSTATUS":"User is not allowed to automatically logging in to remote systems in mobile",
               "IS_TICKETID_REQD_ACW":"false"
            }
         ]
      }
   }
}
我使用JSON.NET进行反序列化,因此我创建了以下模型类(我没有包括JSON对象接收到的所有属性,因为我并不真正需要所有属性)

公共类ResourceAccountListInfo
{
公共操作2操作{get;set;}
}
公共类操作2
{    
公共字符串名称{get;set;}
公共结果结果{get;set;}
公共IList详细信息{get;set;}
}
公共类详细信息2
{     
[JsonProperty(“资源描述”)]
公共字符串RESOURCEDESCRIPTION{get;set;}
[JsonProperty(“资源名称”)]
公共字符串RESOURCENAME{get;set;}
[JsonProperty(“资源ID”)]
公共字符串RESOURCEID{get;set;}
[JsonProperty(“资源类型”)]
公共字符串RESOURCETYPE{get;set;}
[JsonProperty(“DNS名称”)]
公共字符串DNSNAME{get;set;}
[JsonProperty(“账户列表”)]
公共IList帐户列表{get;set;}
}
当我尝试使用此语句反序列化json时,出现以下错误:

  ResourceAccountListInfo resourceAccountListInfo = JsonConvert.DeserializeObject<ResourceAccountListInfo>(json); 
ResourceAccountListInfo ResourceAccountListInfo=JsonConvert.DeserializeObject(json);
错误是:

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.IList`1[T.ViewModels.Details2]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'operation.Details.['RESOURCE ID']', line 1, position 171
无法将当前JSON对象(例如{“name”:“value”})反序列化为类型“System.Collections.Generic.IList`1[T.ViewModels.Details2]”,因为该类型需要JSON数组(例如[1,2,3])才能正确反序列化。
若要修复此错误,请将JSON更改为JSON数组(例如[1,2,3]),或更改反序列化类型,使其成为可以从JSON对象反序列化的正常.NET类型(例如,不是integer之类的基元类型,也不是数组或列表之类的集合类型)。还可以将JsonObjectAttribute添加到类型中,以强制它从JSON对象反序列化。
路径'operation.Details.['RESOURCE ID']',第1行,位置171

我认为问题在于我的JSON对象中有一些属性在模型类中没有映射,这可能是一个原因吗?

您可以将
JObject
dynamic
一起使用:

dynamic json = JObject.Parse(jsonString);
然后以您想要的方式填充模型,而不创建整个类层次结构:

var operationName = json.operation.name;

请注意:使用
dynamic
可以在运行时创建属性。这意味着您将没有intellisense支持,如果您尝试调用不存在的方法或属性,您将获得运行时异常。因此,使用这种方法时要非常小心。

这里的错误消息实际上很有启发性:

无法将当前JSON对象(例如{“名称”:“值”})反序列化为类型“System.Collections.Generic.IList`1[T.ViewModels.Details2]”,因为该类型需要JSON数组(例如[1,2,3])才能正确反序列化。 若要修复此错误,请将JSON更改为JSON数组(例如[1,2,3]),或更改反序列化类型,使其成为可以从JSON对象反序列化的正常.NET类型(例如,不是integer之类的基元类型,也不是数组或列表之类的集合类型)。还可以将JsonObjectAttribute添加到类型中,以强制它从JSON对象反序列化。 路径'operation.Details.['RESOURCE ID']',第1行,位置171

它告诉你的是它有一个对象,你要求它将其反序列化为一个集合。它不能这样做,因为它不是一个集合

您的模型中有:

public IList<Details2> Details { get; set; }
这是一个对象(请注意大括号
{}

因此,您只需将
详细信息
属性更改为:

public Details2 Details { get; set; }

json
details
中的任何属性如果在
Details2
中没有相应的属性,都将被静默忽略。因此,您不需要映射json中的每个属性,只映射您真正关心的属性。

为什么要将
详细信息作为列表?它不是json中的列表,而是一个对象。将您的
public IList Details{get;set;}
更改为
public Details 2 Details{get;set;}
@MattBurland您是100%正确的,但这不会有任何区别,我编辑了我的问题,谢谢您的更正。当然,这会有所不同。这正是错误消息告诉您的,它无法将json中的对象转换为集合,因为它不是集合。否。任何你不关心的属性,都不要映射它们。它们将被忽略。您的
Details2
类已经映射了(我假设)您所关心的属性。您不需要将JSON的所有属性映射到您的C#对象。你只能使用你需要的。重要的是,在反序列化时需要指示数组或列表类型。
  "Details":{  
     "RESOURCE ID":"1",
     "RESOURCE NAME":"test resource",
     "RESOURCE DESCRIPTION":"",
     "RESOURCE TYPE":"Windows",
     "DNS NAME":"172.16.20.101",
     "PASSWORD POLICY":"Strong",
     "DEPARTMENT":"",
     "LOCATION":"",
     "RESOURCE URL":"",
     "RESOURCE OWNER":"admin",
     "ACCOUNT LIST":[  
        {  
           "ISFAVPASS":"false",
           "ACCOUNT NAME":"root",
           "PASSWDID":"1",
           "IS_TICKETID_REQD_MANDATORY":"false",
           "ISREASONREQUIRED":"false",
           "AUTOLOGONLIST":[  
              "Windows Remote Desktop",
              "Remote Desktop"
           ],
           "PASSWORD STATUS":"****",
           "IS_TICKETID_REQD":"false",
           "ACCOUNT ID":"1",
           "AUTOLOGONSTATUS":"User is not allowed to automatically logging in to remote systems in mobile",
           "IS_TICKETID_REQD_ACW":"false"
        }
     ]
  }
public Details2 Details { get; set; }