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

Onl*_*ere 60 c# serialization json poco json.net

这是我简单的UserPOCO课程:

/// <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; }

}
Run Code Online (Sandbox Code Playgroud)

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

private User LoadUserFromJson(string response)
{
    var outObject = JsonConvert.DeserializeObject<User>(response);
    return outObject;
}
Run Code Online (Sandbox Code Playgroud)

这引发了一个例外:

无法将当前JSON对象(例如{"name":"value"})反序列化为类型'System.Collections.Generic.List`1 [CoderwallDotNet.Api.Models.Account]',因为该类型需要JSON数组(例如[ 1,2,3])正确反序列化.

要修复此错误,请将JSON更改为JSON数组(例如[1,2,3])或更改反序列化类型,使其成为普通的.NET类型(例如,不是像整数这样的基本类型,而不是类似的集合类型可以从JSON对象反序列化的数组或List.JsonObjectAttribute也可以添加到类型中以强制它从JSON对象反序列化.路径'accounts.github',第1行,第129位.

从来没有使用过这种DeserializeObject方法,我有点被困在这里.

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

我可以尝试将JSON反序列化为此POCO类吗?

L.B*_*L.B 102

这是一个有效的例子.

关键点是:

  • 宣言 Accounts
  • 使用JsonProperty属性

.

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

-

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;
}
Run Code Online (Sandbox Code Playgroud)

  • 你忘了帐户上的List <>,还是我错过了什么?在我看来,原始问题将Accounts作为列表,但是此解决方案将Accounts作为单个Account对象...而不是数组,而不是列表. (10认同)
  • @huntharo看起来改变的`Accounts`声明 - 从`List <Account>`到`Account` - 是因为示例JSON(在问题中链接)有一个单独的JSON对象 - 不是数组 - 用于` accounts`:``accounts':{"github":"sergiotapia"}` (4认同)

小智 6

将驼峰式JSON字符串反序列化为pascal式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; 
}
Run Code Online (Sandbox Code Playgroud)


Sas*_*cha 5

accounts属性的定义如下:

"accounts":{"github":"sergiotapia"}
Run Code Online (Sandbox Code Playgroud)

您的POCO声明:

public List<Account> Accounts { get; set; }
Run Code Online (Sandbox Code Playgroud)

尝试使用此Json:

"accounts":[{"github":"sergiotapia"}]
Run Code Online (Sandbox Code Playgroud)

项目数组(将要映射到列表)始终放在方括号中。

编辑:帐户Poco将是这样的:

class Account {
    public string github { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

以及其他属性。

编辑2:要没有数组,请使用如下属性:

public Account Accounts { get; set; }
Run Code Online (Sandbox Code Playgroud)

带有类似我在第一次编辑中发布的示例类的内容。


SwD*_*n81 5

您可以创建一个JsonConverter。请参阅此处,以获取与您的问题类似的示例。


Jim*_*Jim 5

按照接受的答案,如果您有 JSON 文本示例,则可以将其插入此转换器,选择您的选项并生成 C# 代码。

如果您在运行时不知道类型,那么这个主题看起来很合适。

动态地将 json 反序列化为传入的任何对象。c#

  • 2021 年 7 月更新 - 该转换器仍然存在于网络上并且运行良好。 (2认同)