0

我有一个部分视图,它显示基于视图模型的许多输入。在某些情况下,其中一些输入不是由局部视图呈现的,但仍用[Required]视图模型中的属性进行修饰。结果,当表单被发送回我的控制器时,ModelState.IsValid返回 false。有没有办法绕过这个?

4

4 回答 4

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.IsValidMarried == true

于 2014-05-22T19:25:27.117 回答
1

我有时会根据特定的 DropDown 或单选按钮选择使表单略有变化。

在您检查之前在您的 Action 方法中,ModelState.IsValid您可以执行类似的操作ModelState.Remove("Object.PropertyName")

注意:属性名称应与呈现给客户端的 ID 相同。用一个 ”。” 对于任何下划线。

    If isSomeCondition Then
        ModelState.Remove("Property1")
        ModelState.Remove("Property2")
    End If

    If ModelState.IsValid() Then
       ...
    End If
于 2014-05-26T12:31:47.677 回答
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);
}

这只是一个示例,但应该清楚如何在有或没有验证的情况下重用相同的模型。

于 2014-05-22T19:14:59.387 回答
1

您应该始终将 VIEW 模型与 DOMAIN 模型分开。这有一个很好的理由,它与安全有关。当您使用域模型作为视图模型时,您很容易受到过度发布和/或发布不足的攻击。您可以在这些页面上阅读更多相关信息:

  1. http://odetocode.com/blogs/scott/archive/2012/03/12/complete-guide-to-mass-assignment-in-asp-net-mvc.aspx
  2. http://blogs.msdn.com/b/rickandy/archive/2012/03/23/securing-your-asp-net-mvc-4-app-and-the-new-allowanonymous-attribute.aspx
  3. https://hendryluk.wordpress.com/tag/asp-net-mvc/

简而言之,如果您不需要一个字段,那么它不应该在您的视图模型中。您应该转换 - 将您的视图模型映射到域模型。尽管它可能很乏味,但它使您的应用程序更加安全。您可以使用一些库来帮助您进行映射,例如 Automapper。

编辑:自从我最初的回答以来,我得出一个结论,处理这种情况的最简单方法是让您的视图模型实现 IValidatableObject 接口,然后在 Validate 方法中编写您的验证逻辑。它不会为您提供客户端验证,但它是在不编写您自己的自定义过滤器的情况下完成基于自定义/场景的验证的最有效和最干净的方式。

你可以在这里阅读更多关于它的信息:http ://weblogs.asp.net/scottgu/class-level-model-validation-with-ef-code-first-and-asp-net-mvc-3

于 2014-05-22T23:36:44.167 回答