我有一个部分视图,它根据视图模型显示许多输入。在某些情况下,某些输入不会由局部视图呈现,但仍在视图模型中使用[Required]
属性进行修饰。因此,当表单回发到我的控制器时,ModelState.IsValid
返回false。有没有办法绕过这个?
答案 0 :(得分:1)
我建议将验证与基础模型分开。
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);
}
这只是一个例子,但应该明确如何在有或没有验证的情况下重复使用相同的模型。
答案 1 :(得分:1)
您可以使用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
更改为false
答案 2 :(得分:1)
您应始终将VIEW模型与DOMAIN模型分开。这有一个很好的理由,它与安全性有关。当您使用域模型作为视图模型时,您很容易受到叠加和/或下冲击攻击。您可以在以下页面上阅读更多相关信息:
简而言之,如果您不需要某个字段,那么它就不应该在您的视图模型中。您应该转换 - 将您的视图模型映射到域模型。虽然它可能很乏味,但它可以使您的应用程序更加安全。您可以使用库来帮助您进行映射,例如Automapper。
编辑:从我最初的答案开始,我得出结论,处理这种情况的最简单方法是让你的视图模型实现IValidatableObject接口,然后在Validate方法中编写验证逻辑。它不会为您提供客户端验证,但它是完成自定义/基于场景的验证的最有效和最简洁的方法,而无需编写自己的自定义过滤器。您可以在此处详细了解:http://weblogs.asp.net/scottgu/class-level-model-validation-with-ef-code-first-and-asp-net-mvc-3
答案 3 :(得分:1)
我根据特定的DropDown或单选按钮选择稍微改变了表单。
在检查ModelState.IsValid
之前,在您的Action方法中,您可以执行ModelState.Remove("Object.PropertyName")
注意 :属性名称应与呈现给客户端的ID相同。用一个 ”。”任何下划线。
If isSomeCondition Then
ModelState.Remove("Property1")
ModelState.Remove("Property2")
End If
If ModelState.IsValid() Then
...
End If