如何使用JSON.NET反序列化部分JSON对象

本文关键字:JSON 对象 反序列化部 NET 何使用 | 更新日期: 2023-09-27 18:08:25

我正在做一个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对象接收到的所有属性,因为我并不真正需要它们)。

public class ResourceAccountListInfo
{
    public Operation2 operation { get; set; }
}
public class Operation2
{    
    public string name { get; set; }
    public Result result { get; set; }
    public IList<Details2> Details { get; set; }    
}
public class Details2
{     
    [JsonProperty("RESOURCE DESCRIPTION")]
    public string RESOURCEDESCRIPTION { get; set; }
    [JsonProperty("RESOURCE NAME")]
    public string RESOURCENAME { get; set; }
    [JsonProperty("RESOURCE ID")]
    public string RESOURCEID { get; set; }
    [JsonProperty("RESOURCE TYPE")]
    public string RESOURCETYPE { get; set; }
    [JsonProperty("DNS NAME")]
    public string DNSNAME { get; set; }
    [JsonProperty("ACCOUNT LIST")]
    public IList<ACCOUNTLIST> ACCOUNTLIST { get; set; }
}

当我尝试使用此语句反序列化json时,我得到以下错误:

  ResourceAccountListInfo resourceAccountListInfo = JsonConvert.DeserializeObject<ResourceAccountListInfo>(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对象里面没有映射模型类,这可能是一个原因吗?

如何使用JSON.NET反序列化部分JSON对象

这里的错误信息实际上很有指导意义:

无法将当前JSON对象(例如{"name":"value"})反序列化为类型'System.Collections.Generic.IList ' 1[T.ViewModels. view]。因为该类型需要一个JSON数组(例如[1,2,3])来正确反序列化。要修复此错误,要么将JSON更改为JSON数组(例如[1,2,3]),要么更改反序列化类型,使其成为可以从JSON对象反序列化的普通。net类型(例如,不是像整数这样的原始类型,也不是像数组或列表这样的集合类型)。还可以将JsonObjectAttribute添加到类型中,以强制它从JSON对象进行反序列化。operation.Details路径"。['RESOURCE ID']',第1行,位置171

它告诉你的是它有一个对象,你已经要求它将它反序列化为一个集合。它不能那样做,因为它一开始就不是一个集合。

你的模型中有:

public IList<Details2> Details { get; set; }

但是在json中对应的details属性是:

  "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"
        }
     ]
  }

这是一个对象(注意花括号{})。

所以你所需要做的就是改变你的Details属性为:
public Details2 Details { get; set; }

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

您可以使用JObjectdynamic:

dynamic json = JObject.Parse(jsonString);

然后以您想要的方式填充您的模型,而无需创建整个类层次结构:

var operationName = json.operation.name;

请注意:使用dynamic,您的属性将在运行时创建。这意味着你将没有智能感知支持,如果你试图调用不存在的方法或属性,你将得到一个运行时异常。所以,使用这种方法要非常小心。