使用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#