使用JsonConvert.DeserializeObject将Json反序列化为C#POCO类

这是我简单的User POCO类:

 /// <summary> /// The User class represents a Coderwall User. /// </summary> public class User { /// <summary> /// A User's username. eg: "sergiotapia, mrkibbles, matumbo" /// </summary> public string Username { get; set; } /// <summary> /// A User's name. eg: "Sergio Tapia, John Cosack, Lucy McMillan" /// </summary> public string Name { get; set; } /// <summary> /// A User's location. eh: "Bolivia, USA, France, Italy" /// </summary> public string Location { get; set; } public int Endorsements { get; set; } //Todo. public string Team { get; set; } //Todo. /// <summary> /// A collection of the User's linked accounts. /// </summary> public List<Account> Accounts { get; set; } /// <summary> /// A collection of the User's awarded badges. /// </summary> public List<Badge> Badges { get; set; } } 

我正在使用的反序列化一个User对象的JSON响应的方法(这个实际的JSON调用在这里 ):

 private User LoadUserFromJson(string response) { var outObject = JsonConvert.DeserializeObject<User>(response); return outObject; } 

这引发了一个例外:

因为types需要一个JSON数组(例如[ 1,2,3])来正确地反序列化。

要解决这个错误,或者把JSON改成一个JSON数组(例如[1,2,3]),或者改变反序列化types,使它成为一个正常的.NETtypes(例如,不是一个原始types,如整数,而不是一个集合types一个数组或列表),可以从一个JSON对象反序列化。 JsonObjectAttribute也可以添加到types中,强制它从JSON对象反序列化。 path'accounts.github',第1行,第129位。

从来没有使用这个DeserializeObject方法之前,我有点卡在这里。

我已经确定POCO类中的属性名称与JSON响应中的名称相同。

我可以尝试将JSON反序列化到此POCO类中?

这是一个工作的例子。

关键点是:

  • Accounts宣言
  • 使用JsonProperty属性

 using (WebClient wc = new WebClient()) { var json = wc.DownloadString("http://coderwall.com/mdeiters.json"); var user = JsonConvert.DeserializeObject<User>(json); } 

 public class User { /// <summary> /// A User's username. eg: "sergiotapia, mrkibbles, matumbo" /// </summary> [JsonProperty("username")] public string Username { get; set; } /// <summary> /// A User's name. eg: "Sergio Tapia, John Cosack, Lucy McMillan" /// </summary> [JsonProperty("name")] public string Name { get; set; } /// <summary> /// A User's location. eh: "Bolivia, USA, France, Italy" /// </summary> [JsonProperty("location")] public string Location { get; set; } [JsonProperty("endorsements")] public int Endorsements { get; set; } //Todo. [JsonProperty("team")] public string Team { get; set; } //Todo. /// <summary> /// A collection of the User's linked accounts. /// </summary> [JsonProperty("accounts")] public Account Accounts { get; set; } /// <summary> /// A collection of the User's awarded badges. /// </summary> [JsonProperty("badges")] public List<Badge> Badges { get; set; } } public class Account { public string github; } public class Badge { [JsonProperty("name")] public string Name; [JsonProperty("description")] public string Description; [JsonProperty("created")] public string Created; [JsonProperty("badge")] public string BadgeUrl; } 

你可以创build一个JsonConverter 。 在这里看到一个类似于你的问题的例子。

另一种更简化的方法是将驼峰式JSONstring反序列化成pascal-Pased POCO对象,方法是使用CamelCasePropertyNamesContractResolver 。

它是Newtonsoft.Json.Serialization命名空间的一部分。 这种方法假设JSON对象和POCO唯一的区别在于属性名称的大小写。 如果属性名拼写不同,则需要使用JsonProperty属性映射属性名称。

 using Newtonsoft.Json; using Newtonsoft.Json.Serialization; . . . private User LoadUserFromJson(string response) { JsonSerializerSettings serSettings = new JsonSerializerSettings(); serSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); User outObject = JsonConvert.DeserializeObject<User>(jsonValue, serSettings); return outObject; } 

accounts属性是这样定义的:

 "accounts":{"github":"sergiotapia"} 

您的POCO指出:

 public List<Account> Accounts { get; set; } 

尝试使用这个Json:

 "accounts":[{"github":"sergiotapia"}] 

项目数组(将被映射到列表)总是被括在方括号中。

编辑:帐户波科将是这样的:

 class Account { public string github { get; set; } } 

也可能是其他属性。

编辑2:没有一个数组使用如下属性:

 public Account Accounts { get; set; } 

像我在第一次编辑中发布的示例类。

 to fix this error either change the JSON to a JSON array (eg [1,2,3]) or change the deserialized type so that it is a normal .NET type (eg not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object.` 

整个消息表明可以序列化为List对象,但input必须是JSON列表。 这意味着你的JSON必须包含

 "accounts" : [{<AccountObjectData}, {<AccountObjectData>}...], 

AccountObject数据是代表您的账户对象或您的徽章对象的JSON

现在看来是这样的

 "accounts":{"github":"sergiotapia"} 

凡帐户是一个JSON对象(用花括号表示),而不是一个JSON对象(数组用括号表示)的数组,这是你想要的。 尝试

 "accounts" : [{"github":"sergiotapia"}] 

这不是我想到的。 如果你只有在运行时才知道的genericstypes,你该怎么办?

 public MyDTO toObject() { try { var methodInfo = MethodBase.GetCurrentMethod(); if (methodInfo.DeclaringType != null) { var fullName = methodInfo.DeclaringType.FullName + "." + this.dtoName; Type type = Type.GetType(fullName); if (type != null) { var obj = JsonConvert.DeserializeObject(payload); //var obj = JsonConvert.DeserializeObject<type.MemberType.GetType()>(payload); // <--- type ????? ... } } // Example for java.. Convert this to C# return JSONUtil.fromJSON(payload, Class.forName(dtoName, false, getClass().getClassLoader())); } catch (Exception ex) { throw new ReflectInsightException(MethodBase.GetCurrentMethod().Name, ex); } } 

沿着接受的答案,如果你有一个JSON文本样本,你可以插入到这个转换器 ,select你的选项,并生成C#代码。

如果您在运行时不知道该types,则该主题看起来像是适合的。

dynamic反序列化json到传入的任何对象。c#