繁体   English   中英

ASP.NET MVC-验证表单输入

[英]ASP.NET MVC - Validate Form Input

我是ASP.NET MVC的新手。 我正在尝试验证一些用户输入。 我的观点背后的模型如下所示:

public class ViewModel
{
  [Required]
  public int? Minimum { get; set; }

  [Required]
  public int? Maximum { get; set; }
}

我的视图(.cshtml文件)如下所示

@model Website.Models.ViewModel
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    ...
<div class="row">
  <div class="col-sm-6"><input class="form-control input-sm" id="Minimum" name="Minimum" type="text" /></div>                            
  <div class="col-sm-6"><input class="form-control input-sm" id="Maximum" name="Maximum" type="text" /></div>
</div>
   ...

<br />
<button type="submit" class="btn btn-primary">Save</button>
}

我的控制器如下所示:

public class MyController 
{
  public ActionResult Edit(int? id)
  {
    var model = new ViewModel();
    return View(model);
  }

  [HttpPost]
  public ActionResult Edit(ViewModel model)
  {
    if (ModelState.IsValid) {
      var result = await model.SaveAsync();
      return RedirectToAction("Edit", new { id = result.DemandId, u = "true" });
    }
    return View(model);
  }
}

我的代码正在验证是否提供该字段。 但是,我需要添加一些业务规则。 例如,我需要确保“最大值”大于“最小值”。 如果不是,那么我需要给用户一个错误。 我打算有更复杂的验证方案。

我的问题是, 如何在ASP.NET MVC中处理这些高级验证方案?

如果您要进行很多验证,我建议您深入研究Fluent Validation库。

安装后,您需要在MVC应用程序的Application_Start事件期间配置FluentValidationModelValidatorProvider (位于FluentValidation.Mvc命名空间中)。

这使Fluent Validation可以挂接到ModelState并在ModelState.IsValid等上触发。

protected void Application_Start() {

    /* Your other initializing code */

    FluentValidationModelValidatorProvider.Configure();
}

然后创建您的验证器

public class ViewModelValidator : AbstractValidator<ViewModel> {

    public ViewModelValidator() {
        RuleFor(x => x.Minimum).NotNull();
        RuleFor(x => x.Maximum).NotNull.GreaterThan(x => x.Minimum)
    }

}

并将其挂钩到您的ViewModel上。

[Validator(typeof(ViewModelValidator))]
public class ViewModel
{
     [Required]
     public int? Minimum { get; set; }

     [Required]
     public int? Maximum { get; set; }
}

这是所有内置验证及其易于创建的自定义数据库驱动验证的列表。

您需要从IValidatableObject派生您的类,看看这篇有用的文章:

http://weblogs.asp.net/scottgu/class-level-model-validation-with-ef-code-first-and-asp-net-mvc-3

一种方法是拥有一个方法(在控制器或单独的验证器类上,您将模型提供给该验证器进行验证)。

这样,您可以根据需要进行许多复杂的验证(击中数据库/服务/文件等,而不会污染您的POCO View模型)

为简单起见,让它内联到控制器中:

[HttpPost]
public ActionResult Edit(ViewModel model)
{
    ValidateEditViewModel(model);
    if (ModelState.IsValid) {

内部ValidateEditViewModel:

private void ValidateEditViewModel(ViewModel model){
    if(model.. // something is wrong)
    {
        // this sets ModelState.IsValid = false
        ModelState.AddModelError("< PropertyNameThatIsInError >", "The item is removed from your cart");  
    }
}

更好的是拥有一个验证器类,该验证器类通过DI注入到控制器中,然后在整个过程中使用(这是更可测试的和SOLID的)。

我倾向于有一个I <ControllerName> ControllerValidator类(因此对于Homecontroller,它是IHomeControllerValidator),由一个<Controllername> Validator(HomeValidator)具体类实现,并通过unity / dependencyResolver在控制器构造中注入。

做工精美。

最后一个扩展是具有<TValidator>的基本控制器类,该类接受验证器类实例实例,并将其存储在使用该基本类的所有控制器的一致位置。

public class BaseController<TValidator> : Controller{
    protected TValidator validator;
    public BaseController(TValidator validator){
         this.validator = validator;
    }
}

所以HomeController是

public class HomeController : BaseController<IHomeControllerValidator>
{
    public HomeController(IHomeControllerValidator validator) : base(validator)
    {
    }
}

高温超导

在视图模型中使用IValidatableObject接口。

public class ViewModel : IValidatableObject
{
    [Required]
    public int? Minimum { get; set; }

    [Required]
    public int? Maximum { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var results = new List<ValidationResult>();

        if (this.Minimum > this.Maximum)
        {
            results.Add(new ValidationResult("Maximum must be larger than Minimum"));
        }

        return results;
    }
}

Minimum > Maximum时,这将强制ModelState.IsValid为false。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM