我有一个很大的对象,我使用@Html.Serialize()
进行序列化:
[Serializable]
public class ModelB
{
public List<ModelA> ListOfModelA { get; set; }
// more stuff
}
此对象包含一个包含多个属性的类的对象列表。其中一些我将它们包含在我的视图中,而另一些我甚至懒得把它们作为隐藏字段,就像我在序列化模型中一样。
[Serializable]
public class ModelA
{
public string StringA { get; set; }
public string StringB { get; set; }
// more stuff
public string HiddenStringA { get; set; }
public string HiddenStringB { get; set; }
// more stuff
}
现在,当我使用我的更改回发表单时,我会重新构建我的模型,然后使用从表单中获取的值字典更新它。
[HttpPost]
public ActionResult Edit([Deserialize] ModelTwo model,
FormCollection form)
{
TryUpdateModel(model, form.ToValueProvider());
// more stuff
}
我介入我的代码,就在我进行更新之前,我看到我的反序列化模型包含一个ListOfModelA列表,而ListOfModelA又包含应该存在的所有元素,在其中我可以看到所有HiddenStringA和HiddenStringB属性。然后我偷看表格,我看到一个字典,上面有这样的键:
ListOfModelA[0].StringA
ListOfModelA[0].StringB
ListOfModelA[1].StringB
ListOfModelA[1].StringB
虽然没有其他属性的键,如下所示:
ListOfModelA[0].HiddenStringA
接下来,我再向前迈进一步,让代码执行TryUpdateModel。现在,查看ListOfModelA属性,所有元素都被替换为所有隐藏值为null的元素。就好像更新重建了整个元素(它具有有限的信息),而不是只更新它拥有信息的属性。
这是预期的行为吗?有没有办法保留我的模型,只更新字典中有键的属性?
谢谢,
帕诺斯
答案 0 :(得分:0)
我的问题比上面描述的问题更复杂,但是我为特定设计找到的解决方案大致如下。我序列化作为列表的模型部分,并通过操作的参数绑定整个模型。这样我就避免使用TryUpdateModel,虽然这不是导致我麻烦的原因。然后,我从表单创建的模型中将非空值注入到反序列化模型中,最后我将后者的相应部分指向前者。
[HttpPost]
public ActionResult Edit(ModelTwo model,
[Deserialize] List<ModelA> serializedList)
{
serializedList.InjectFrom<NonNullLoopValueInjection>(model.ListOfModelA);
model.ListOfModelA = serializedList;
// more stuff
}
对于注射,我使用Value Injecter,其中NonNullLoopValueInection
定义如下
public class NonNullLoopValueInjection : LoopValueInjection
{
protected override bool AllowSetValue(object value)
{
return value != null;
}
}
也许不是最好的设计,但它有效,它可能会让我更好。任何反馈都非常受欢迎。