مروری بر Fluent Validation در MVC
دوشنبه 15 آذر 1395اعتبارسنجیِ داده ها (Data Validation) یکی از ویژگی های کلیدی هر برنامه وب میباشد . اعتباری سنجی معمولا روی مولفه های UI ، برای جلوگیری از بروز خطا و گرفتن اطلاعاتی که لازم است حتما از کاربر گرفته شود ، اعمال میشود . در این مقاله قصد داریم ، اعتبارسنجی داده ها با Fluent Validation را در ASP.Net MVC ارائه دهیم .
در برنامه وب ، همین امر از SQL Injection و Script Injection جلوگیری میکند .
همانطور که میدانید در حال حاضر فریمورک های Net. متفاوتی برای اعتبارسنجی ارائه شده است . ما میتوانیم با استفاده از Javascript و jQuery مولفه های UI را در سمت Client اعتبارسنجی کنیم .
در ASP.Net MVC ، از Data Annotation Validation برای اعتبار سنجی استفاده میکنیم . استفاده از قوانین اعتبار سنجی و ارائه یک پیام در هنگام بروز خطا ، در اینجا ، کار بسیار ساده ای میباشد . فقط مشکل آن قوانین اعتبار سنجی است که به View Model ضمیمه شده است .
در برنامه های بزرگ ASP.Net MVC ، ما Entity را از View MOdel جدا میکنیم . دامنه Entity های ما معطوف به همهی برنامه ها میشود اما View Model ها مربوط به یک برنامه خاص هستند . ما در عمل به جای استفاده از تمام دامنه Entity از فیلدهایی که مورد نیاز ما هستند استفاده خواهیم کرد . ما از Automapper در طرح ریزی دامنه Entity در View Model برای ساده و کارآمد کردن View Model استفاده میکنیم . زمانی که شروط اعتبارسنجی را در View Model قرار میدهیم ، آن پیچیده میشود .
اگر برنامه در مقیاس های بزرگ انجام میشود ، اعتبارسنجی ها و Model را در یک کلاس میگذاریم . در اینجا ما قاعده های ، Seprate of Concern و Single Responsilbility را نقض میکنیم . این باعث بروز یک مشکل در توسعه test driven،برای مشتریان میشود .
برای حل این نوع از مشکلات ، ما یک گزینه داریم ، که آن فریمورکی است با نام Fluent Validation .
ما میتوانیم قوانین اعتبارسنجی را کاملا از Model جدا کنیم .کتابخانه Fluent Validation راه های ساده ای را برای Unit Test قوانین اعتبارسنجی فراهم میآورد ؛ این ، زمانی که ما میخواهیم به قوانین اعتبارسنجی Dependecy ای را Inject کنیم ، به ما کمک خواهد کرد .
برای مثال ، ما میتوانیم برای اعتبارسنجی فیلدهای UI و نشان دادن پیام خطا به کاربران ، اطلاعاتی را از یک پایگاه داده یا یک منبع خارجی بخوانیم . زمانی که نیاز است که منطق اعتبارسنجی از مشخصه های Model جدا باشد ، قوانین seperation of Concern و Single Responsilbilty را رعایت میکنیم . Fluent Validation برعکس Unit Testing که کمی دردسر دارد ، بسیار ساده است و ما میتوانیم وابستگی ها را inject کنیم یا یک پایگاه داده یا هرگونه Service دیگر را برای اعتبارسنجی مشخصه هایمان، فراخوانی کنیم .
آن از تعداد زیادی قوانین از پیش تعریف شده ، پیام های خطای محلی ، استفاده از Object Data ها در پیام های خطا ، متد های اعتبارسنجی و اعتبار سنجی های شرطی سفارشی شده ، پشتیبانی میکند . تعدادی از قوانین را تایید میکند ، اگر object data با شرط همخوانی داشت ، مجموعه قوانین - مجموعه ای از قوانین ، اشیاءِ اعتبارسنجی aggregated ، نام مجموعه ها و مشخصه هایی که با نام مشخصه های ASP.Net MVC درگیر است ، را تایید میکند .
حال برای اینکه درک بهتری از Fluent Validation داشته باشید ، یک مثال از آن را برای شما ارائه میدهیم .
همانطور که در زیر نمایش داده شده است ، EmployeeModel را ایجاد کنید :
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace FluentValidationDemo.Models { public class EmployeeModel { public int EmployeeId { get; set; } public string EmployeeName { get; set; } public string DepartmentNo { get; set; } public string Address { get; set; } public int Salary { get; set; } public string Email { get; set; } } }
یک کلاس با نام EmployeeValidator و کدهای زیر را درون آن بگذارید :
using FluentValidation; using FluentValidationDemo.Models; using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace FluentValidationDemo { public class EmployeeValidator : AbstractValidator<EmployeeModel> { public EmployeeValidator() { EmployeeEntities e = new EmployeeEntities(); RuleFor(x => x.EmployeeId).NotEmpty().WithMessage("EmployeeId is required"); RuleFor(x => x.EmployeeName).NotEmpty().WithMessage("EmployeeName is required"); EmployeeEntities e = new EmployeeEntities(); Custom(model => { var employeevalidation = e.Employees.FirstOrDefault(emp => emp.EmployeeName == model.EmployeeName); if (employeevalidation != null) { return new FluentValidation.Results.ValidationFailure("EmployeeName", model.EmployeeName+"is a Existing employee."); } return null; }); RuleFor(x => x.EmployeeName).Length(10,20).WithMessage("Name should be between 10 and 20 characters"); RuleFor(x => x.DepartmentNo).NotEmpty().WithMessage("DepartmentNo is not valid"); RuleFor(x => x.Address).NotEmpty().WithMessage("Address is required"); RuleFor(x => x.Salary).NotEmpty().WithMessage("Salary is not valid"); RuleFor(x => x.Email) .Matches(@"^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$").WithMessage("Not a valid email") .NotEmpty(); Custom(model=> { var employeevalidation=e.Employees.FirstOrDefault(emp=>emp.Email==model.Email); if(employeevalidation!=null) { return new FluentValidation.Results.ValidationFailure("Email", "Email is already in Use Please try another EMail "); } return null; }); } } }
کلاس EmployeeValidator ، کلاس EmployeeModel را به عنوان ورودی دریافت میکند
AbstractValidator<EmployeeModel>
در اینجا ما اعتبارسنجی های مختلفی همانند required , lenght , range و regular expression برای EmployeeModel در نظر میگیریم .
RuleFor(x => x.EmployeeId).NotEmpty().WithMessage("The EmployeeId field is required"); RuleFor(x => x.EmployeeName).NotEmpty().WithMessage("EmployeeName is required");
ما متوانیم در سمت سرور داده ها را اعتبارسنجی کنیم ، مقداد داده ها را قبل از ذخیره سازی در پایگاه داده چک کنیم . برای مثال ، Email یا Username ، که میتوانند از قبل در پایگاه داده وجود داشته باشند ، برای جلوگیری از ورود داده های تکراری میتوانید از تکه کد زیر استفاده کنید :
EmployeeEntities e = new EmployeeEntities(); Custom(model => { var employeevalidation = e.Employees.FirstOrDefault(emp => emp.EmployeeName == model.EmployeeName); if (employeevalidation != null) { return new FluentValidation.Results.ValidationFailure("EmployeeName", model.EmployeeName + "is a Existing employee."); } return null; });
حال ، ما EmployeeEntity را که یک entity از یک جدول Employee از پایگاه داده است را فراخوانی میکنیم :
آموزش asp.net mvc
- ASP.net MVC
- 3k بازدید
- 2 تشکر