如何解析传入的JSON字符串,其中模型I';m反序列化为包含JSON

本文关键字:JSON 包含 反序列化 模型 何解析 字符串 | 更新日期: 2023-09-27 18:27:37

我有一个看起来像这样的模型:

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中?

如何解析传入的JSON字符串,其中模型I';m反序列化为包含JSON

这里的技巧是不要直接反序列化到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的每个属性,我们将其字符串表示附加到数据属性。