【问题标题】:Proper way of passing in a entity (form) to a controller action将实体(表单)传递给控制器​​操作的正确方法
【发布时间】:2012-09-05 10:47:15
【问题描述】:

我正在编写一个创建新用户的控制器操作。目前,控制器操作将 用户实体模型 作为参数。

我想知道是否应该在自己的视图模型中从前端传递值,然后在后端提取值并创建实体?

public ActionResult AddUser(User user)
{
  context.Users.Add(user);
  context.SaveChanges();
}

public ActionResult AddUser(UserViewModel userViewModel)
{
  var user = new User(userViewModel.Name);
  context.User.Add(user);
  context.SaveChanges();
}

谢谢!

【问题讨论】:

    标签: asp.net-mvc-3 controller action


    【解决方案1】:

    与大多数事情一样,有多种方法可以做到这一点。最终在这种情况下,它通常归结为个人喜好。

    当我做同样的事情时,我经常问自己,传递给方法的内容是否真的是有效的User。我喜欢保持我的模型在内部防止无效状态,而不是依赖调用代码来保持模型的有效性。

    因此,有时有些动作会接收到描述模型但不完全构建模型本身的信息。在这些情况下,我更喜欢使用视图模型。如果没有其他原因,除了一致性之外,这通常会导致我全面使用视图模型。

    如果我需要页面上多个模型的信息,它特别有用。拥有一个由我需要的信息组合而成的视图模型,而不是像 Tuple 这样的两个模型,这对我来说感觉更干净。这也允许我向视图模型(计算字段、标志等)添加对视图有用但会污染业务对象的附加属性。 (用于显示/隐藏某些表单元素、验证项等的开关)

    您通常可以通过注意对象 (User) 和数据结构 (UserViewModel) 之间的区别来找到自己对这类问题的偏好)。在传统的面向对象意义上,User 应该隐藏其数据成员并提供功能接口,而像 UserViewModel 这样的平面数据结构将暴露其数据成员并且没有任何有意义的功能。

    由于视图只是想绑定到数据成员,我通常使用平面视图模型而不是域对象。

    【讨论】:

      【解决方案2】:

      学术方法是创建一个额外的视图模型类,它只公开您需要显示的数据或用户需要输入信息的字段,并将它们映射到您的域模型,如您的第二个示例中所示。

      但是对于小型应用程序或当您需要模型中的所有字段时,我认为将域模型对象传递给视图是绝对可以的。

      另一个需要考虑的重要事项是安全/验证。当使用隐式 mvc 映射机制和完整的域模型时,不良用户可能会将值发送到您不希望存储在数据库中的控制器。 使用单独的视图模型类涉及显式映射步骤,您必须明确告诉系统您要映射到域模型的视图模型中的哪个字段(= 用户输入的数据)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-29
        相关资源
        最近更新 更多