更新实体场景中的asp.net mvc自定义模型绑定

更新实体场景中的asp.net mvc自定义模型绑定,asp.net,asp.net-mvc,Asp.net,Asp.net Mvc,嗨,我有一个关于模型绑定的问题。假设您有一个显示在表单中的现有数据库实体,并且希望编辑一些详细信息,一些属性(例如createddate等)未绑定到表单,在模型绑定期间,这些属性未分配给模型,因为它们不在http post数据或querystrong等上,因此它们的属性为空。在我的控制器更新方法中,我只想 公共行动结果更新(实体ent) { //将更改保存到数据库 } 但是,由于某些属性在ent中为null,它们会覆盖不属于表单post数据的现有数据库字段,因此正确的处理方法是什么?我尝试了隐藏

嗨,我有一个关于模型绑定的问题。假设您有一个显示在表单中的现有数据库实体,并且希望编辑一些详细信息,一些属性(例如createddate等)未绑定到表单,在模型绑定期间,这些属性未分配给模型,因为它们不在http post数据或querystrong等上,因此它们的属性为空。在我的控制器更新方法中,我只想

公共行动结果更新(实体ent) { //将更改保存到数据库 }


但是,由于某些属性在ent中为null,它们会覆盖不属于表单post数据的现有数据库字段,因此正确的处理方法是什么?我尝试了隐藏字段来保存数据,但模型绑定似乎没有将隐藏字段分配给模型。如果您有任何建议,我们将不胜感激。

您不应该将实体发送到视图,您应该发送一个称为DTO(数据传输对象)或ViewModel的精简版本

仅将属性发送到您希望用户使用该操作更新的视图(因此也就是回发的表单)

在POST处理程序中,您可以验证属性并将其复制到实体中

如果您有很多属性,自动映射器可以提供帮助

比如:

public class User
{
    int id;
    string name;
    string email;
}

public class EditUserEmailDto
{
    string email;
}

// get
public ActionResult EditEmail(int id,)
{
    return View("EditEmail", new EditUserEmailDto());
}    

// post
public ActionResult EditEmail(int id, EditUserEmailDto dto)
{
    if(!ModelState.IsValid)
        return View("EditEmail", dto);

    var user = userRepo.Get(id);
    user.email = dto.email;
    userRepo.Save(user);

    return;
}

这很有道理,安德鲁,谢谢你的回答。我认为您的解决方案适用于一个简单的场景,当您使用一个既适用于保存场景又适用于更新场景的自定义模型绑定器,并且需要为类型而不是viewdata指定值时,情况如何。您将如何处理这个问题?以及您将如何利用模型验证等功能?回复第一条评论:我不知道您的意思,您能解释一下这个问题吗?关于第二条评论,我在活页夹中进行验证,这样可以保持帖子处理程序整洁。我将更新答案以显示该处理程序的示例,但这里的验证位可能太多了。基本上,我扩展了
DefaultModelBinder
,覆盖
BindModel
,调用
base.BindModel
,然后从IoC容器中获取模型类型的验证器,验证模型,然后在
ModelState