Fluent Validation в ASP .NET MVC приложениях. Основы
Рубрика: ASP .NET MVC -> c# -> Программирование
Метки: Fluent Validation | валидация | программирование
Просмотров: 10770
Валидация данных в ASP .NET MVC приложениях у многих ассоциируется с применением технологии аннотации данных (Data Annotation). Если ты хоть раз подключал для создания проверок пространство имен System.ComponentModel.DataAnnotations , то однозначно понимаешь, о чем я говорю. Технология «Data Annotation» позволяет организовать гибкую проверку моделей. Для самых простых случаев есть предопределенные атрибуты, позволяющие упростить проверку таких вещей как номер телефона, email, длина строки и т.д. Если требуются нестандартные проверки - всегда есть возможность написать собственный валидатор.
Во всех своих ASP .NET MVC проектах я старался использовать именно DataAnnotations, но однажды я наткнулся на библиотеку Fluent Validation и решил познакомиться с ее функционалом. Как оказалось позже, библиотека пользуется популярностью среди англоговорящих разработчиков и многие проверки с ее помощью делать проще, чем с DataAnnotations.
Библиотека доступна для MVC проектов, начиная с третьей версии. Среди киллер фич можно выделить удобство применения, наличие готовых валидаторов из коробки, гибкость разработки своих валидаторов и удобство проверки зависимых полей модели. Например, у нас есть поле «field», значение которого требуется проверять, если «field2» установлено в true. Подобную проверку можно описать одной строчкой кода:
RuleFor(x => x.field).NotEmpty().When(x => x.field2);
Скажу по секрету, изначально именно эта возможность заставила меня сфокусироваться на этой библиотеке и протестировать ее.
Добавляем Fluent Validation к рабочему проекту
Чтобы потренироваться в применении библиотеки Fluent Validation я создал новый ASP .NET MVC4 проект типа Internet Application. Этот тип проекта уже содержит рабочую систему аутентификации/авторизации и готовые страницы для выполнения регистрации и входа на сайт. Проверка всех отправляемых пользователем данных реализована через «DataAnnotation». В рамках данного примера мы попробуем избавится от Data Annotation и воспользоваться услугами библиотеки Fluent Validation.
Итак, для добавления библиотеки Fluent Validation к уже созданному проекту необходимо в консоле «Package Manager Console» необходимо выполнить следующую команду:
Install-Package FluentValidation.MVC4
На момент написания заметки последняя версия библиотеки имела индекс 5.0.0.1. Если команда выполнилась успешно, то в консоле будет выведен текст вроде этого:
PM> Install-Package FluentValidation.MVC4 Attempting to resolve dependency 'FluentValidation (≥ 5.0.0.1)'. Installing 'FluentValidation.MVC4 5.0.0.1'. Successfully installed 'FluentValidation.MVC4 5.0.0.1'. Adding 'FluentValidation.MVC4 5.0.0.1' to Fluent Validtion. Successfully added 'FluentValidation.MVC4 5.0.0.1' to Fluent Validtion.
Выбираем модель для опытов
Для первоначальной демонстрации библиотеки Fluent Validation, попробуем избавить одну из моделей тестового проекта от DataAnnotation. Открываем файл AccountModels (в нем описаны все модели) и находим код модели RegisterModel. Код, сгенерированный Visual Studio приведен ниже:
public class RegisterModel
{
[Required]
[Display (Name = "User name" )]
public string UserName { get; set; }
[Required]
[StringLength (100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display (Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
Из кода видно, что для каждого поля установлен соответствующий атрибут валидации. Таким образом, поля модели RegisterModel должны быть в обязательном порядке заполнены (атрибут Required) . Поле с паролем должно содержать минимум 6 символов, а общая длина строки не должна превышать 100 символов (атрибуты StringLength и MinimumLength). Для поля ConfirmPassword используется атрибут Compare, который указывает на необходимость сравнения значения поля ConfirmPassword со значением поля Password (пароли же должны совпадать).
Заменяем DataAnnotation на Fluent Validation
Попробуем переписать рассмотренный выше пример с применением Fluent Validation. Для этого создадим новый класс RegisterModelValidator():
using FluentValidation;
namespace Fluent_Validtion.Models.Validators
{
public class RegisterModelValidator : AbstractValidator <RegisterModel>
{
public RegisterModelValidator()
{
RuleFor(x => x.UserName)
.NotNull();
RuleFor(x => x.Password)
.NotNull()
.Length(6, 100);
RuleFor(x => x.ConfirmPassword)
.Equal(x => x.Password);
}
}
}
В конструкторе класса RegisterModelValidator описываются правила для проверки свойств модели. Пример демонстрирует установку следующих правил:
Инициализируем валидатор
Валидатор на базе Fluent Validation полностью готов, теперь его необходимо подключить к проверяемой модели. Делается это путем добавления атрибута FluentValidation.Attributes.Validator()
:
using FluentValidation;
using Fluent_Validtion.Models.Validators;
[FluentValidation.Attributes. Validator( typeof( RegisterModelValidator))]
public class RegisterModel
{
[Display (Name = "User name")]
public string UserName { get; set; }
[DataType(DataType.Password)]
[Display (Name = "Password")]
public string Password { get ; set; }
[DataType(DataType.Password)]
[Display (Name = "Confirm password")]
public string ConfirmPassword { get ; set; }
}
В выше приведенном коде я убрал все атрибуты DataAnnotation и добавил к модели созданный нами валидатор. Модифицированный проект почти готов к старту, остается лишь прописать вызов инициализации Fluent Validation в Application_Start(), объявленный в файле Global.asax:
using FluentValidation.Mvc;
namespace Fluent_Validtion
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration .RegisterAllAreas();
WebApiConfig .Register( GlobalConfiguration .Configuration);
FilterConfig .RegisterGlobalFilters( GlobalFilters .Filters);
RouteConfig .RegisterRoutes( RouteTable .Routes);
BundleConfig .RegisterBundles( BundleTable .Bundles);
AuthConfig .RegisterAuth();
//Выполняем инициализацию Fluent Validation
FluentValidationModelValidatorProvider .Configure();
}
}
}
Теперь можно запускать пример и тестировать работу библиотеки Fluent Validation на практике. Визуально все работает отлично и теперь можно переходить к следующему шагу – написанию Unit-тестов, но об этом мы поговорим в следующей части заметки.
Обрати внимание, в шаблоне проекта типа Internet Application включена валидация данных на клиенте. Если ты специально введешь неправильные данные, то тест работы Fluent Validation будет не удачным, т.к. сработает проверка на клиенте. Перед запуском проекта отключи проверку данных на клиенте путем внесения изменений в Web.config:
<add key = "ClientValidationEnabled" value = "false" />
<add key = "UnobtrusiveJavaScriptEnabled" value ="false" />
2014-03-15 в 00:50:53
А где продолжение? Когда будут остальные части и будут ли вообще?
2014-03-16 в 02:40:21
Продолжение обязательно будет. Блог только запущен и сейчас находится в стадии наполнения. По FluentValidaion уже готовы две заметки. Одна из них будет опубликована на следующей неделе. Следи за новостями ;-)