如何将JSON反序列化为对象?

时间:2011-11-23 21:41:42

标签: c# json json.net deserialization

我正在尝试使用JSON.Net将JSON对象反序列化为C#对象。

我要创建的对象是MonthlyPerformance,其中包含Type列表,其中包含Categories列表,其中包含Funds列表。它们被定义为:

public class MonthlyPerformance
{
    public List<Type> Types { get; set; }
}

public class Type
{
    public int Id { get; set; }
    public string CountryId { get; set; }
    public string Name { get; set; }

    public List<Category> Categories { get; set; }

    public Type()
    {

    }
}

public class Category
{
    public int Id { get; set; }
    public string CountryId { get; set; }
    public string Name { get; set; }

    public List<ConfigurationFund> Funds { get; set; }

    public Category()
    {

    }
}

public class Fund
{
    public int Id { get; set; }
    public string CountryId { get; set; }
    public string Name { get; set; }

    public Fund()
    {

    }
}

我认为以下会这样做,但事实并非如此。它只是创建一个Type对象的实例,其中所有内容都为null:

var file = File.ReadAllText(filePath);

var types = JsonConvert.DeserializeObject<Type>(file);

这是我正在使用的JSON:

{
  "MonthlyPerformance": {
    "Type": [
      {
        "id": "65",
        "countryId": "IE",
        "name": "Irish Domestic Funds (Gross)",
        "Category": [
          {
            "id": "25003334",
            "countryId": "IE",
            "name": "UK Equity",
            "ConfigurationFund": [
              {
                "id": "25000301",
                "countryId": "IE",
                "name": "Aviva Irl UK Equity Fund"
              },
              {
                "id": "25000349",
                "countryId": "IE",
                "name": "New Ireland UK Equity 9"
              }
            ]
          },
          {
            "id": "25003339",
            "countryId": "IE",
            "name": "Irish Equity",
            "Fund": [
              {
                "id": "25000279",
                "countryId": "IE",
                "name": "Friends First Irish Equity G"
              },
              {
                "id": "25000305",
                "countryId": "IE",
                "name": "Irish Life Celticscope 2 G"
              }
            ]
          }
        ]
      },
      {
        "id": "80",
        "countryId": "IE",
        "name": "Irish Individual Pensions",
        "Category": [
          {
            "id": "25003347",
            "countryId": "IE",
            "name": "Asia Pacific Ex-Japan Equity",
            "Fund": [
              {
                "id": "25001789",
                "countryId": "IE",
                "name": "Aviva Irl Pacific Basin Eq"
              },
              {
                "id": "25002260",
                "countryId": "IE",
                "name": "Ir Life Pacific Eq Indexed  P"
              }
            ]
          },
          {
            "id": "25003365",
            "countryId": "IE",
            "name": "Flexible Equity",
            "Fund": [
              {
                "id": "25003238",
                "countryId": "IE",
                "name": "Friends First Protected Equity Plus Fund S2"
              },
              {
                "id": "25003267",
                "countryId": "IE",
                "name": "Friends First Protected Equity Plus Bond G"
              }
            ]
          }
        ]
      }
    ]
  }
}

我需要做些什么才能让它发挥作用?

已修改为包含MonthlyPerformance

5 个答案:

答案 0 :(得分:2)

您是否会考虑使用dynamic对象而不是反序列化对象? (未声明MonthlyPerformanceTypeCategoryFund

Facebook C# SDK get user language/region

Google Maps v3 geocoding server-side

用法:

dynamic jobj = JsonUtils.JsonObject.GetDynamicJsonObject(JsonString);
foreach (var item in jobj.MonthlyPerformance.Type)
{
    Console.WriteLine(item.name);
    foreach (var category in item.Category)
    {
        Console.WriteLine("\t" + category.name);
        if (category.ConfigurationFund != null)
        {
            foreach (var fund in category.ConfigurationFund)
            {
                Console.WriteLine("\t\t" + fund.name);
            }
        }
    }
}

所需的帮助程序类是here

答案 1 :(得分:2)

您的课程上面的代码在第一眼就看起来是正确的。

我已成功使用以下类(JavaScriptSerializer)反序列化JSON。用法如下

using System.Web.Script.Serialization;

JavaScriptSerializer js = new JavaScriptSerializer();
string file = File.ReadAllText(filePath);
MonthyPerformance json = js.Deserialize<MonthlyPerformance>(file);

哦,并将[Serializable]添加到每个类的类属性

[Serializable]
class whatever{}

答案 2 :(得分:2)

我认为问题出在你的Json字符串中。

"Type": [ ... ] 

应该是

"Types": [ ... ]  

Types是应反序列化的属性名称,您错误地Type改为类名。

Categories类中的Type属性也是如此。

我只是从Json字符串中删除了"MonthlyPerformance" root,它就像魅力一样。当然还有Json.NET。

以下是修改过的Json的片段,其中包含相应的属性名称(通知,类型,类别,基金以及缺少MonthlyPerformance根目录)

{
    "Types": [ 
    { 
    "id": "65", 
    "countryId": "IE", 
    "name": "Irish Domestic Funds (Gross)", 
    "Categories": [ 
        { 
        "id": "25003334", 
        "countryId": "IE", 
        "name": "UK Equity", 
        "Funds": [ 
            { 
            "id": "25000301", 
            "countryId": "IE", 
            "name": "Aviva Irl UK Equity Fund" 
            }, 
            { 
            "id": "25000349", 
            "countryId": "IE", 
            "name": "New Ireland UK Equity 9" 
        } 
    ] 
}

答案 3 :(得分:0)

您的属性名称与JSON的属性名称不匹配。我希望序列化失败。

鉴于您发布的JSON,我希望您的c#类看起来像这样。我不熟悉JSON.net,但我认为他们有一个属性装饰器,允许你指定c#prop匹配的JSON属性的名称。

public class MonthlyPerformance
{
    public List<Type> Type { get; set; }
}

public class Type
{
    public int id { get; set; }
    public string countryId { get; set; }
    public string Name { get; set; }

    public List<Category> Category { get; set; }

    public Type()
    {

    }
}

public class Category
{
    public int id { get; set; }
    public string countryId { get; set; }
    public string name { get; set; }

    public List<Fund> ConfigurationFund{ get; set; }

    public Category()
    {

    }
}

public class Fund
{
    public int id { get; set; }
    public string countryId { get; set; }
    public string name { get; set; }

    public Fund()
    {

    }
}

答案 4 :(得分:0)

这是我用于JSON反序列化...

using System.Web.Script.Serialization;

namespace blahblah
{
    public partial class AccessTierService : ServiceBase
    {
        public static T ia_deserialize_json<T>(string json_string)
        {
            try
            {
                if ((String.Compare(json_string, null) == 0) ||
                    (String.Compare(json_string, "") == 0) ||
                    (String.Compare(json_string, String.Empty) == 0))
                {
                    return default(T);
                }
                JavaScriptSerializer serializer = new JavaScriptSerializer();
                return (T)serializer.Deserialize<T>(json_string);
            }
            catch (Exception)
            {
                return default(T);
            }
        }
    }
}

并称之为......

login_request = ia_deserialize_json<ol_login_request>(body_string);