我们的数据库中有一个字段确实应该是一个布尔值,但由于某种原因,原始开发人员将其设置为CHAR,将其设置为“1”或“0”。
[Column("CHARGEABLE")]
[StringLength(1)]
private string Chargeable { get; set; }
我希望我的模型将此字段表示为布尔值,因此我想我可以在模型中添加一个属性来包装它:
[NotMapped]
public bool ChargeableTrue
{
get
{
return Chargeable == "1" ? true : false;
}
set
{
Chargeable = value ? "1" : "0";
}
}
现在在我的View上我只显示了EditorFor(ChargeableTrue),但是当我点击save时它实际上并没有更新它。
我认为正在发生的事情是,当模型更新时,它仍然试图从View中获取'Chargeable'的值,即使我没有在那里显示它。并且由于没有输入字段,它只是变为空并最终将其保存到数据库。
if (ModelState.IsValid)
{
db.Entry(call).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
在这种情况下,人们应该做些什么?
答案 0 :(得分:2)
使用视图模型并在控制器上进行映射。
答案 1 :(得分:2)
根据KMan的回答,这是扩展版本,以防你不熟悉创建视图模型。
我们的想法是,您的域对象实际上并不是您想要从视图中更新的内容。相反,您可以创建一个中间人,也可以包含特定于视图的项目(例如填充下拉列表的对象列表)。
public class MyViewModel {
public bool Chargeable { get; set; }
}
现在你可以这样做:
@* In view *@
Html.EditorFor(m => m.Chargeable)
// In controller
public ActionResult Save(MyViewModel model) {
if (ModelState.IsValid) {
var domainObject = new MyObject() {
Chargeable = model.Chargeable ? "1" : "0"
};
// the rest of your code using domainObject
}
}
我会考虑创建一个域对象构造函数的重载,它接受你的视图模型以将映射保存在一个地方。我通常使用AutoMapper之类的工具来映射对象或手动扩展方法。
视图模型通常包含域对象属性的子集,但可以包含所有属性或更多属性,如列表,可见性状态等。它们非常有用,我从未完成过一个MVC项目我没有用过它们。