我的模型看起来像这样:
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
}
注意:Id
和EditedOn
将始终包含在内,但此JSON中可以包含任意数量的其他字段。我需要以某种方式将JSON反序列化到模型中,其中不属于模型的字段是Data
中的JSON对象存储。
var row = JsonConvert.DeserializeObject<ClientRow>(incoming);
这会为我提供一个填充了Id
和EditedOn
的对象,但当然未填充Data
。如何获取所有剩余字段并将该JSON存储在Data
?
答案 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
后,我们可以手动映射我们知道应该始终相同的两个属性Id
和EditedOn
。
自ExpandoObjects
实现IDictionary
以来,我们可以迭代属性的键值对。对于我们发现的每个已经映射的Id
或EditedOn
的属性,我们将其字符串表示附加到data属性。