MVC中使用FluentValidation验证实体

1、FluentValidation介绍

  FluentValidation是与ASP.NET DataAnnotataion Attribute验证实体不同的数据验证组件,提供了将实体与验证分离开来的验证方式,同时FluentValidation还提供了表达式链式语法。

  2、安装FluentValidation

  FluentValidation地址:http://fluentvalidation.codeplex.com/

  使用Visual Studio的管理NuGet程序包安装FluentValidation及FluentValidation.Mvc

  3、通过ModelState使用FluentValidation验证

  项目解决方案结构图:

  

  实体类Customer.cs:

复制代码
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace Libing.Portal.Web.Models.Entities
{ public class Customer
    { public int CustomerID { get; set; } public string CustomerName { get; set; } public string Email { get; set; } public string Address { get; set; } public string Postcode { get; set; } public float? Discount { get; set; } public bool HasDiscount { get; set; }
    }
}
复制代码

  数据验证类CustomerValidator.cs:

复制代码
using System; using System.Collections.Generic; using System.Linq; using System.Web; using FluentValidation; using Libing.Portal.Web.Models.Entities; namespace Libing.Portal.Web.Models.Validators
{ public class CustomerValidator : AbstractValidator<Customer> { public CustomerValidator()
        {
            RuleFor(customer => customer.CustomerName).NotNull().WithMessage("客户名称不能为空");
            RuleFor(customer => customer.Email)
                .NotEmpty().WithMessage("邮箱不能为空")
                .EmailAddress().WithMessage("邮箱格式不正确");
            RuleFor(customer => customer.Discount)
                .NotEqual(0)
                .When(customer => customer.HasDiscount);
            RuleFor(customer => customer.Address)
                .NotEmpty()
                .WithMessage("地址不能为空")
                .Length(20, 50)
                .WithMessage("地址长度范围为20-50字节");
        }
    }
}
复制代码

  控制器类CustomerController.cs:

复制代码
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using FluentValidation.Results; using Libing.Portal.Web.Models.Entities; using Libing.Portal.Web.Models.Validators; namespace Libing.Portal.Web.Controllers
{ public class CustomerController : Controller
    { public ActionResult Index()
        { return View();
        } public ActionResult Create()
        { return View();
        }

        [HttpPost] public ActionResult Create(Customer customer)
        {
            CustomerValidator validator = new CustomerValidator();
            ValidationResult result = validator.Validate(customer); if (!result.IsValid)
            {
                result.Errors.ToList().ForEach(error => {
                    ModelState.AddModelError(error.PropertyName, error.ErrorMessage);
                });
            } if (ModelState.IsValid)
            { return RedirectToAction("Index");
            } return View(customer);
        }
    }
}
复制代码

  View页面Create.cshtml,该页面为在添加View时选择Create模板自动生成:

复制代码
@model Libing.Portal.Web.Models.Entities.Customer

@{
    Layout = null;
} <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>Create</title> </head> <body> @using (Html.BeginForm()) 
    {
        @Html.AntiForgeryToken() <div class="form-horizontal"> <h4>Customer</h4> <hr /> @Html.ValidationSummary(true) <div class="form-group"> @Html.LabelFor(model => model.CustomerName, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.CustomerName)
                    @Html.ValidationMessageFor(model => model.CustomerName) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Email, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Email)
                    @Html.ValidationMessageFor(model => model.Email) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Address, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Address)
                    @Html.ValidationMessageFor(model => model.Address) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Postcode, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Postcode)
                    @Html.ValidationMessageFor(model => model.Postcode) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Discount, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Discount)
                    @Html.ValidationMessageFor(model => model.Discount) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.HasDiscount, new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.HasDiscount)
                    @Html.ValidationMessageFor(model => model.HasDiscount) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="submit" value="Create" class="btn btn-default" /> </div> </div> </div> } </body> </html>
复制代码

  运行效果:

  

  4、通过设置实体类Attribute与验证类进行验证

  修改实体类Customer.cs:

复制代码
using System; using System.Collections.Generic; using System.Linq; using System.Web; using FluentValidation.Attributes; using Libing.Portal.Web.Models.Validators; namespace Libing.Portal.Web.Models.Entities
{
    [Validator(typeof(CustomerValidator))] public class Customer
    { public int CustomerID { get; set; } public string CustomerName { get; set; } public string Email { get; set; } public string Address { get; set; } public string Postcode { get; set; } public float? Discount { get; set; } public bool HasDiscount { get; set; }
    }
}
复制代码

  修改Global.asax.cs:

复制代码
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; using FluentValidation.Attributes; using FluentValidation.Mvc; namespace Libing.Portal.Web
{ public class MvcApplication : System.Web.HttpApplication
    { protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes); // FluentValidation设置 DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
            ModelValidatorProviders.Providers.Add(new FluentValidationModelValidatorProvider(new AttributedValidatorFactory()));
        }
    }
}
复制代码


评论回复