一、FluentValidation介紹html
FluentValidation是與ASP.NET DataAnnotataion Attribute驗證明體不一樣的數據驗證組件,提供了將實體與驗證分離開來的驗證方式,同時FluentValidation還提供了表達式鏈式語法。ide
二、安裝FluentValidationui
FluentValidation地址:http://fluentvalidation.codeplex.com/spa
使用Visual Studio的管理NuGet程序包安裝FluentValidation及FluentValidation.Mvc3d
三、經過ModelState使用FluentValidation驗證code
項目解決方案結構圖:orm
實體類Customer.cs:htm
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:blog
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:ci
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>
運行效果:
四、經過設置實體類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())); } } }