将Json字符串反序列化为C#模型

时间:2015-10-01 12:39:15

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

我有以下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.

2 个答案:

答案 0 :(得分:3)

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

    "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<string,Period>

那么第一个属性:

        "label": "Period"

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

因此错误

  

转换值时出错&#34;期间&#34;输入&#39; CMS.WebApi.Controllers.ActivitiesController + Period&#39;

它试图转换字符串&#34; Period&#34;上课时间。

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

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

但我的猜测是你希望有超过1个句号,所以你会有#34; 0&#34;,&#34; 1&#34;,&#34; 2&#34; ......等等。

如果没有将一些代码放在一起进行测试,我不确定是否有一个好方法可以做到。

您可能想尝试让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"
        }
    ]
}

答案 1 :(得分:1)

这是你可以做到的,因为“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; }
}