如何解析传入的JSON字符串,其中我反序列化的模型包含JSON?

时间:2015-12-22 03:11:27

标签: c# json

我的模型看起来像这样:

public class ClientRow
{
    public Guid Id { get; set; }
    public string Data { get; set; }
    public DateTime EditedOn { get; set; }
}

Data属性包含JSON。

当UI更新其中一行并提交它时,它将作为JSON格式的单个字符串进入我的控制器操作。例如:

{
    Id: <guid>,
    Product: "Generic Widget",
    Price: 25.99,
    Quantity: 25,
    EditedOn: 12/13/2015
}

注意:IdEditedOn将始终包含在内,但此JSON中可以包含任意数量的其他字段。我需要以某种方式将JSON反序列化到模型中,其中不属于模型的字段是Data中的JSON对象存储。

var row = JsonConvert.DeserializeObject<ClientRow>(incoming);

这会为我提供一个填充了IdEditedOn的对象,但当然未填充Data。如何获取所有剩余字段并将该JSON存储在Data

1 个答案:

答案 0 :(得分:2)

这里的诀窍是不直接反序列化到ClientRow对象。相反,我们希望反序列化为ExpandoObject,这允许我们在运行时动态添加属性。

string json = "{Id: \"2db55af1-109c-46aa-ba36-e61ae6e5a6e1\", Product: \"Generic Widget\", Price: 25.99, Quantity: 25, EditedOn: \"12/13/2015\"}";  
dynamic deserialized = JsonConvert.DeserializeObject<ExpandoObject>(json, new ExpandoObjectConverter());

ClientRow cr = new ClientRow
{
    Id = new Guid(deserialized.Id),
    EditedOn = DateTime.ParseExact(deserialized.EditedOn, "MM/dd/yyyy", CultureInfo.InvariantCulture)
};

IDictionary<string, object> propertyValues = (IDictionary<string, object>)deserialized;
foreach (var property in propertyValues)
{
    if (!(property.Key.Equals("Id") || property.Key.Equals("EditedOn")))
    {
        cr.Data += property.Value.ToString() + " ";
    }
}

// cr now contains our final deserialized result
Console.WriteLine(JsonConvert.SerializeObject(cr));

我们拥有ExpandoObject后,我们可以手动映射我们知道应该始终相同的两个属性IdEditedOn

ExpandoObjects实现IDictionary以来,我们可以迭代属性的键值对。对于我们发现的每个已经映射的IdEditedOn的属性,我们将其字符串表示附加到data属性。