防止 MVC 4 过度发布的最佳方法是什么?
根据 MS 消息来源,[Bind] 属性应该是通过防止传入的表单值进入数据库来防止过度发布的最简单方法。使用最新版本的 MVC 和 EF,这似乎没有按预期/宣传的那样工作,除非我遗漏了一些重要的东西。
从Wrox Professional ASP.NET MVC 4(Jon Galloway 的第 7 章)开始,以下类应防止过度发布:
[Bind(Exclude="IsAdmin")]
public class User
{
public int ID { get; set; }
public string FirstName { get; set; }
public bool IsAdmin { get; set; }
}
但是 [Bind] 属性所做的只是阻止表单提交值绑定到模型。然后模型有一个空白/默认值,它被写回数据库。在这种情况下,它将确保您每次使用此模型调用 .SaveChanges() 时 IsAdmin = false。任何“真实”值都会被覆盖。这是一个巨大的安全失败。
另一种语法 - 将 [Bind] 放在 Edit 控制器操作参数中 - 执行完全相同的操作:
public ActionResult Edit([Bind(Exclude = "IsAdmin")] User user)
当调用 .SaveChanges() 时,所有“真实”值都会被覆盖,这与 K. Scott Allen 关于该主题的博客文章相矛盾:http: //odetocode.com/blogs/scott/archive/2012/03/11/complete-guide- to-mass-assignment-in-asp-net-mvc.aspx
唯一的选择似乎是一系列专用的 ViewModel 都与 Automapper 连接。虽然安全,但这似乎是一个非常令人头疼的问题,尤其是在:
- 您可能对 Create、Edit、Index 和 Detail 操作有不同的要求,需要不同的 ViewModel
- 您可能需要公开一些只读字段(例如 Edit 操作上的 CreatedBy),这些字段不能在属性上具有 [ReadOnly] 属性,因为它们是由 Create 操作更新的
我知道有人会回应说你永远不应该将数据模型绑定到视图,但这是默认的模板行为以及它在几乎所有文档中的显示方式。此外,MVC + EF 应该让生活更轻松,而不是更难,而与 AutoMapper 连接的大量 ModelView 类并不是我认为更容易的事情。
那么有人知道如何使 [Bind] 功能如宣传的那样吗?