مروری بر Fluent Validation در MVC

اعتبارسنجیِ داده ها (Data Validation) یکی از ویژگی های کلیدی هر برنامه وب میباشد . اعتباری سنجی معمولا روی مولفه های UI ، برای جلوگیری از بروز خطا و گرفتن اطلاعاتی که لازم است حتما از کاربر گرفته شود ، اعمال میشود . در این مقاله قصد داریم ، اعتبارسنجی داده ها با Fluent Validation را در ASP.Net MVC ارائه دهیم .

مروری بر Fluent Validation در 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 از پایگاه داده است را فراخوانی میکنیم :

دانلود فایل های ضمیمه مخصوص اعضای سایت می باشد !
کاربر مهمان! جهت دانلود و استفاده از امکانات سایت لطفا وارد سایت شوید و یا ثبت نام کنید
دانلود نسخه ی PDF این مطلب