防止 MVC 4 过度发布的最佳方法是什么?
根据 MS 的消息来源,[Bind] 属性应该是通过阻止传入的表单值进入数据库来防止过度发布的最简单方法。使用最新版本的 MVC 和 EF,这似乎并没有按预期/宣传的那样工作,除非我错过了一些重要的东西。
From Wrox 专业 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] 放在编辑控制器操作参数中 - 执行完全相同的操作:
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
唯一的选择似乎是一系列与 Automapper 连接的专用 ViewModel。虽然安全,但这似乎是一个令人头疼的问题,尤其是在以下情况下:
- 您可能对创建、编辑、索引和详细信息操作有不同的要求,需要不同的 ViewModel
- 您可能需要公开一些只读字段(例如编辑操作上的 CreatedBy),这些字段在属性上不能具有 [ReadOnly] 属性,因为它们是由创建操作更新的
我知道有人会回应说你应该never将数据模型绑定到视图,但这是默认的模板行为以及几乎所有文档中显示的方式。此外,MVC + EF 应该创造生活easier, not harder,并且与 AutoMapper 连接的大量 ModelView 类并不是我认为更容易的。
那么有人知道如何使 [Bind] 发挥广告中的功能吗?