【问题标题】:Deserialize Json string to C# model将 Json 字符串反序列化为 C# 模型
【发布时间】:2015-10-01 12:39:15
【问题描述】:

我有以下 JSON 对象,可以访问我的 Web API 控制器:

{
    "id": "13",
    "title": "party",
    "periods": {
        "0": {
            "label": "Period",
            "start_date": "2015-04-20",
            "end_date": "2015-04-29"
        }
    }
}

我想尝试将其直接反序列化为我在 C# 中拥有的模型,但我也做不到。

这是我的模型:

    public class PeriodsModel
    {
        [JsonProperty("id")]
        public int id { get; set; }

        [JsonProperty("title")]
        public string title { get; set; }

        [JsonProperty("periods")]
        public Periods periods { get; set; }
    }
    public class Periods
    {
        [JsonProperty("0")]
        public Dictionary<string,Period> period { get; set; }
    }

    public class Period
    {
        [JsonProperty("label")]
        public string label { get; set; }

        [JsonProperty("start_date")]
        public string start_date { get; set; }

        [JsonProperty("end_date")]
        public string end_date { get; set; }
    }

这是我在控制器中的方法:

public void Put([FromBody]JToken jsonbody)
{
    var myJsonObject = JsonConvert.SerializeObject(jsonbody);
    PeriodsModel model = JsonConvert.DeserializeObject<PeriodsModel>(myJsonObject);
}

这是我得到的错误消息:

An exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.dll but was not handled in user code

Additional information: Error converting value "Period" to type 'CMS.WebApi.Controllers.ActivitiesController+Period'. Path 'periods.0.label', line 1, position 62.

【问题讨论】:

    标签: c# json json.net asp.net-web-api2


    【解决方案1】:

    错误信息是正确的。深入研究数据......你有:

        "0": {
            "label": "Period",
            "start_date": "2015-04-20",
            "end_date": "2015-04-29"
        }
    

    你试着把它放进去:

    public class Periods
    {
        [JsonProperty("0")]
        public Dictionary<string,Period> period { get; set; }
    }
    
    public class Period
    {
        [JsonProperty("label")]
        public string label { get; set; }
    
        [JsonProperty("start_date")]
        public string start_date { get; set; }
    
        [JsonProperty("end_date")]
        public string end_date { get; set; }
    }
    

    更具体地说,这个 JSON:

        {
            "label": "Period",
            "start_date": "2015-04-20",
            "end_date": "2015-04-29"
        }
    

    正在反序列化为Dictionary&lt;string,Period&gt;


    那么第一个属性:

            "label": "Period"
    

    需要反序列化为&lt;string, Period&gt; 对。 左侧"label" 正确转换为string 但右侧是字符串"Period",并且该字符串无法反序列化为类类型Period

    因此错误

    将值“Period”转换为类型“CMS.WebApi.Controllers.ActivitiesController+Period”时出错

    它正在尝试将字符串“Period”转换为Period类。


    您在这里想要做什么并不完全清楚,但如果periods 中只有一个"0",那么您可以将属性更改为:

    public class Periods
    {
        [JsonProperty("0")]
        public Period period { get; set; }
    }
    

    但我的猜测是你会想要超过 1 个句点,所以你会有“0”、“1”、“2”……等等。

    如果没有整理一些代码来测试它,我不确定是否有一个好的方法来做到这一点。

    您可能想尝试让PeriodsModel 拥有:

        [JsonProperty("periods")]
        public Dictionary<string, Period> periods { get; set; }
    

    然后你就根本不需要 Periods 类了。

    虽然通常当我要传递的东西数量不定时,我只使用 JSON 数组,例如:

    {
        "id": "13",
        "title": "party",
        "periods": [
            {
                "label": "Period1",
                "start_date": "2015-04-20",
                "end_date": "2015-04-29"
            }, {
                "label": "Period2",
                "start_date": "2015-04-20",
                "end_date": "2015-04-29"
            }, {
                "label": "Period3",
                "start_date": "2015-04-20",
                "end_date": "2015-04-29"
            }
        ]
    }
    

    【讨论】:

    • 是的,我也想要一个对象数组。但我与 Json 在前端的格式无关,我只假设在服务器端处理它,因此我的问题。
    • @grimsan55 在这种情况下,我会尝试将PeriodsModel 更改为拥有属性:Dictionary&lt;string, Period&gt; periods { get; set; },看看是否可行。
    • 是的,可以,但我如何访问让我们以简单的方式说 end_date ?
    • @grimsan55 我认为这会起作用:model.periods["0"].start_date 因为model.periods 是带有键“0”、“1”、“2”等的Dictionary……所以你会像往常一样访问字典。
    • 谢谢,不知道为什么我想不通。我会把你的答案标记为正确的,因为你给出了如此详细的解释,即使阿萨德也给出了正确的答案。跨度>
    【解决方案2】:

    这是你可以做到的,因为“0”更像是一个键而不是一个属性变量:

    public class PeriodsModel
    {
        [JsonProperty("id")]
        public int id { get; set; }
    
        [JsonProperty("title")]
        public string title { get; set; }
    
        [JsonProperty("periods")]
        public Dictionary<string, Period> periods { get; set; }
    }
    
    public class Period
    {
        [JsonProperty("label")]
        public string label { get; set; }
    
        [JsonProperty("start_date")]
        public string start_date { get; set; }
    
        [JsonProperty("end_date")]
        public string end_date { get; set; }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-15
      • 2021-09-02
      相关资源
      最近更新 更多