我有一个基于视图模型显示许多输入的局部视图。在某些情况下,其中一些输入不是由局部视图渲染的,但仍在视图模型中使用[Required]
属性进行修饰。因此,当表单被发回给我的控制器时,ModelState.IsValid
返回false。有没有办法绕过这个?如何防止隐藏字段干扰MVC中的服务器端验证?
回答
我建议将您的验证与您的基本模型分开。
public class MyModel
{
public string MyString { get; set; }
public string MyHiddenField { get; set; }
}
public interface IMyModel_ValidateMystringOnly
{
[Required]
string MyString { get; set; }
}
[MetadataType(TypeOf(IMyModel_ValidateMystringOnly))]
public class MyModel_ValidateMystringOnly : MyModel
这允许您创建任意数量的验证类型,并且只在需要时验证您想要的内容。
public ActionResult ShowMyModel()
{
var model = new MyModel(); // or Respository.GetMyModel() whatever..
View(model);
}
public ActionResult ValidateModel(MyModel_ValidateMystringOnly model)
{
if (ModelState.IsValid)
{
// Hey Validation!
}
// MyModel_ValidateMyStringOnly is a MyModel
// so it can be passed to the same view!
return View("ShowMyModel", model);
}
这只是一个例子,但应该清楚如何在有或无验证的情况下重复使用相同的模型。
您可以使用Foolproof有条件地验证您的字段。这样,只有在需要时才需要它们,正如链接示例中所示。
private class Person
{
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public bool Married { get; set; }
[RequiredIfTrue("Married")]
public string MaidenName { get; set; }
}
在这个例子中,MaidenName
只会改变你ModelState.IsValid
为假,如果Married == true
你应该总是您的视图模型从你的域模型分开。这有一个很好的理由,它与安全性有关。当您使用域模型作为视图模型时,您很容易受到重发和/或底层攻击的攻击。你可以阅读更多关于它在这些网页:
- http://odetocode.com/blogs/scott/archive/2012/03/12/complete-guide-to-mass-assignment-in-asp-net-mvc.aspx
- http://blogs.msdn.com/b/rickandy/archive/2012/03/23/securing-your-asp-net-mvc-4-app-and-the-new-allowanonymous-attribute.aspx
- https://hendryluk.wordpress.com/tag/asp-net-mvc/
总之,如果你并不需要一个字段,则它不应该在你的视图模型。您应该转换 - 将您的视图模型映射到域模型。虽然它可能很乏味,但它使您的应用程序更安全。您可以使用库来帮助您进行Automapper等映射。
编辑:由于我原来的答案,我已经得出结论,处理这种类型的情况最简单的方法是让您的视图模型实现IValidatableObject接口,然后在验证方法内写入您的验证逻辑。它不会为您提供客户端验证,但它是完成基于自定义/方案验证的最有效和最干净的方式,无需编写自己的自定义过滤器。
你可以阅读更多关于它在这里:有时http://weblogs.asp.net/scottgu/class-level-model-validation-with-ef-code-first-and-asp-net-mvc-3
这是一个视图模型而不是域模型。基本上这是一个局部视图,有多种类型的输入,用户可以从中选择。但是输入的数量和类型是可配置的。但是需要显示任何显示的输入。 – Mykroft
我已经使用方法,其中的形式略有变化基于特定的下拉或单选按钮选择。
内,您的操作方法,你检查你ModelState.IsValid
可以这样做ModelState.Remove("Object.PropertyName")
注前:属性名应该是一样的呈现给客户端的ID。用一个 ”。”对于任何下划线。
If isSomeCondition Then
ModelState.Remove("Property1")
ModelState.Remove("Property2")
End If
If ModelState.IsValid() Then
...
End If
- 1. 防止双击服务器端验证
- 2. FlaskWTF验证器可以防止隐藏表单字段
- 3. jQuery和ASP.NEt MVC验证:验证防止对服务器
- 4. 需要隐藏字段验证mvc
- 5. 服务器端验证所需字段
- 6. 必填字段验证服务器端
- 7. AngularJS:防止隐藏表单字段被验证
- 8. 隐藏和显示字段仍使用ASP.NET MVC 2验证隐藏字段客户端验证
- 9. 骨干:部分客户端验证+服务器端验证
- 10. 客户端验证未在asp.net MVC工作隐藏字段3
- 11. 如何验证隐藏字段
- 12. 隐藏字段验证
- 13. 不验证隐藏字段
- 14. 验证隐藏字段
- 15. EmberJS:如何防止Ember干扰jQuery.extend?
- 16. 如何防止引导干扰主题
- 17. JQuery验证:验证隐藏字段
- 18. 如何禁用某个字段的服务器端验证?
- 19. 防止隐藏字段的变更
- 20. ASP.Net MVC验证(服务器端)
- 21. 服务器端验证ASP.NET MVC
- 22. 服务器端验证防止数据库错误
- 23. 服务器端<form>标记防止jQuery验证插件验证
- 24. 如何验证服务器端的CaptchaMVC?
- 25. MVC服务器端字段验证无效方法中的模型
- 26. 如何使用jquery验证验证隐藏字段?
- 27. 隐藏的模板字段值在服务器端不可用
- 28. 无法访问服务器端的隐藏字段值
- 29. 在服务器端获取隐藏字段的空值
- 30. 如何禁用服务器端验证mvc web api控制器
我要说的是,你应该改变你的视图模型,但很难在不知道的情况说。您可以手动“从ModelState中删除错误”,请参阅:http://stackoverflow.com/questions/14008561/is-there-a-strongly-named-way-to-remove-modelstate-errors-in-asp-net- mvc –
当帖子内容绑定到视图模型时,字段的源是输入[type = hidden]还是input [type = text]并不重要。如果有一个值,它将被绑定,否则不会。之后将进行模型验证。 – gustavodidomenico
mvc不验证该字段,它正在验证该类。所以如果你的类有一个必需的属性,并且你发布了一个'x'类,它不会是有效的,你必须手动删除它或创建另一个没有所需文件的类 –