C# ASP.NET MVC-验证表单输入

C# ASP.NET MVC-验证表单输入,c#,asp.net-mvc,C#,Asp.net Mvc,我是ASP.NETMVC新手。我正在尝试验证一些用户输入。我的视图后面的模型如下所示: public class ViewModel { [Required] public int? Minimum { get; set; } [Required] public int? Maximum { get; set; } } public class MyController { public ActionResult Edit(int? id) { var mo

我是ASP.NETMVC新手。我正在尝试验证一些用户输入。我的视图后面的模型如下所示:

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

  [Required]
  public int? Maximum { get; set; }
}
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);
  }
}
我的视图(.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>
}
我的代码正在验证是否提供了该字段。但是,我需要添加一些业务规则。例如,我需要确保最大值大于最小值。如果不是,那么我需要给用户一个错误。我打算有更复杂的验证场景


我的问题是,我应该如何在ASP.NET MVC中处理这些高级验证场景?

如果需要从IValidatableObject派生类,请阅读这篇有用的文章:


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


在视图模型中使用
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;
    }
}
public类ViewModel:IValidatableObject
{
[必需]
公共int?最小值{get;set;}
[必需]
公共int?最大值{get;set;}
公共IEnumerable验证(ValidationContext ValidationContext)
{
var results=新列表();
如果(this.Minimum>this.maxium)
{
结果。添加(新的ValidationResult(“最大值必须大于最小值”);
}
返回结果;
}
}

当视图模型中使用
IValidatableObject
界面时,这将强制
ModelState.IsValid
为false

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;
    }
}
public类ViewModel:IValidatableObject
{
[必需]
公共int?最小值{get;set;}
[必需]
公共int?最大值{get;set;}
公共IEnumerable验证(ValidationContext ValidationContext)
{
var results=新列表();
如果(this.Minimum>this.maxium)
{
结果。添加(新的ValidationResult(“最大值必须大于最小值”);
}
返回结果;
}
}

这将强制
ModelState.IsValid在
Minimum>Maximum
时为false。如果您要进行大量验证,我建议您深入到库中

一旦安装,您需要在Mvc应用程序的
应用程序启动
事件期间配置
FluentValidationModelValidatorProvider
(位于
FluentValidation.Mvc
命名空间中)

这使得Fluent验证能够挂接到
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)
    }

}

下面是一个示例,它可以轻松创建自定义的、数据库驱动的验证

如果您要进行大量验证,我建议您深入到库中

一旦安装,您需要在Mvc应用程序的
应用程序启动
事件期间配置
FluentValidationModelValidatorProvider
(位于
FluentValidation.Mvc
命名空间中)

这使得Fluent验证能够挂接到
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)
    }

}

下面是一个示例,它可以轻松创建自定义的、数据库驱动的验证

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

通过这种方式,您可以随心所欲地进行详细的验证(在不污染POCO视图的情况下访问数据库/服务/文件等)

为了简单起见,让我们将其内联到控制器:

[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");  
    }
}
private void validateEdit视图模型(视图模型模型){
如果(模型..//出现问题)
{
//这将设置ModelState.IsValid=false
AddModelError(“”,“该项目已从购物车中删除”);
}
}
更好的是有一个验证器类,它通过DI注入控制器,然后在整个过程中使用(这是更可测试和可靠的)

我倾向于使用IControllerValidator类(因此,对于Homecontroller,IHomeControllerValidator),该类由Validator(HomeValidator)具体类实现,并根据控制器构造通过unity/dependencyResolver注入

工作得很漂亮

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

public class BaseController<TValidator> : Controller{
    protected TValidator validator;
    public BaseController(TValidator validator){
         this.validator = validator;
    }
}
公共类BaseController:控制器{
受保护的TValidator验证器;
公共BaseController(TValidator验证器){
this.validator=验证程序;
}
}
所以HomeController是

public class HomeController : BaseController<IHomeControllerValidator>
{
    public HomeController(IHomeControllerValidator validator) : base(validator)
    {
    }
}
公共类HomeController:BaseController
{
公共家庭控制器(IHomeControllerValidator验证器):基本(验证器)
{
}
}

HTH

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

通过这种方式,您可以随心所欲地进行详细的验证(在不污染POCO视图的情况下访问数据库/服务/文件等)

为了简单起见,让我们将其内联到控制器:

[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");  
    }
}
private void validateEdit视图模型(视图模型模型){
如果(模型..//出现问题)
{
//这将设置ModelState.IsValid=false
AddModelError(“”,“该项目已从购物车中删除”);
}
}
更好的是有一个验证器类,它通过DI注入控制器,然后在整个过程中使用(这是更可测试和可靠的)

我倾向于使用IControllerValidator类(因此,对于Homecontroller,IHomeControllerValidator),该类由验证器实现