Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Проверка валидации






Если мы просто вызовем что-то типа:

var registerUser = new UserView()

{

Email = " user@sample.com",

Password = " 123456",

ConfirmPassword = " 1234567",

AvatarPath = " /file/no-image.jpg",

BirthdateDay = 1,

BirthdateMonth = 12,

BirthdateYear = 1987,

Captcha = " 1234"

};

var result = controller.Register(registerUser);

То, во-первых, никакая неявная валидация не выполнится, а во-вторых, у нас там есть session и мы ее не проинициализировали, она null и всё – ошибка. Так что проверку валидации (та, что в атрибутах) будем устраивать через отдельный класс. Назовем его Валидатор Валидаторович (/Tools/Validator.cs):

public class ValidatorException: Exception

{

public ValidationAttribute Attribute { get; private set; }

 

public ValidatorException(ValidationException ex, ValidationAttribute attribute)

: base(attribute.GetType().Name, ex)

{

Attribute = attribute;

}

}

 

public class Validator

{

public static void ValidateObject< T> (T obj)

{

var type = typeof(T);

var meta = type.GetCustomAttributes(false).OfType< MetadataTypeAttribute> ().FirstOrDefault();

if (meta! = null)

{

type = meta.MetadataClassType;

}

 

var typeAttributes = type.GetCustomAttributes(typeof(ValidationAttribute), true).OfType< ValidationAttribute> ();

var validationContext = new ValidationContext(obj);

foreach (var attribute in typeAttributes)

{

try

{

attribute.Validate(obj, validationContext);

}

catch (ValidationException ex)

{

throw new ValidatorException(ex, attribute);

}

}

 

var propertyInfo = type.GetProperties();

foreach (var info in propertyInfo)

{

var attributes = info.GetCustomAttributes(typeof(ValidationAttribute), true).OfType< ValidationAttribute> ();

foreach (var attribute in attributes)

{

var objPropInfo = obj.GetType().GetProperty(info.Name);

try

{

attribute.Validate(objPropInfo.GetValue(obj, null), validationContext);

}

catch (ValidationException ex)

{

throw new ValidatorException(ex, attribute);

}

}

}

}

}

 

 

Итак, что тут у нас происходит. Вначале мы получаем все атрибуты класса T, которые относятся к типу ValidationAttribute:

var typeAttributes = type.GetCustomAttributes(typeof(ValidationAttribute), true).OfType< ValidationAttribute> ();

var validationContext = new ValidationContext(obj);

foreach (var attribute in typeAttributes)

{

try

{

attribute.Validate(obj, validationContext);

}

catch (ValidationException ex)

{

throw new ValidatorException(ex, attribute);

}

}

 

Потом аналогично для каждого свойства:

var propertyInfo = type.GetProperties();

foreach (var info in propertyInfo)

{

var attributes = info.GetCustomAttributes(typeof(ValidationAttribute), true).OfType< ValidationAttribute> ();

foreach (var attribute in attributes)

{

var objPropInfo = obj.GetType().GetProperty(info.Name);

try

{

attribute.Validate(objPropInfo.GetValue(obj, null), validationContext);

}

catch (ValidationException ex)

{

throw new ValidatorException(ex, attribute);

}

}

}

Если валидация не проходит, то происходит исключение, и мы оборачиваем его в ValidatorException, передавая еще и атрибут, по которому произошло исключение.

Теперь по поводу капчи и Session. Мы должны контроллеру передать контекст (MockHttpContext):

var controller = DependencyResolver.Current.GetService< Areas.Default.Controllers.UserController> ();

var httpContext = new MockHttpContext().Object;

ControllerContext context = new ControllerContext(new RequestContext(httpContext, new RouteData()), controller);

controller.ControllerContext = context;

controller.Session.Add(CaptchaImage.CaptchaValueKey, " 1111");

И теперь всё вместе:

[Test]

public void Index_RegisterUserWithDifferentPassword_ExceptionCompare()

{

//init

var controller = DependencyResolver.Current.GetService< Areas.Default.Controllers.UserController> ();

var httpContext = new MockHttpContext().Object;

ControllerContext context = new ControllerContext(new RequestContext(httpContext, new RouteData()), controller);

controller.ControllerContext = context;

 

//act

var registerUserView = new UserView()

{

Email = " user@sample.com",

Password = " 123456",

ConfirmPassword = " 1234567",

AvatarPath = " /file/no-image.jpg",

BirthdateDay = 1,

BirthdateMonth = 12,

BirthdateYear = 1987,

Captcha = " 1111"

};

try

{

Validator.ValidateObject< UserView> (registerUserView);

}

catch (Exception ex)

{

Assert.IsInstanceOf< ValidatorException> (ex);

Assert.IsInstanceOf< System.ComponentModel.DataAnnotations.CompareAttribute> (((ValidatorException)ex).Attribute);

}

}

Запускаем, и всё получилось. Но капча проверяется непосредственно в методе контроллера. Специально для капчи:

[Test]

public void Index_RegisterUserWithWrongCaptcha_ModelStateWithError()

{

//init

var controller = DependencyResolver.Current.GetService< Areas.Default.Controllers.UserController> ();

var httpContext = new MockHttpContext().Object;

ControllerContext context = new ControllerContext(new RequestContext(httpContext, new RouteData()), controller);

controller.ControllerContext = context;

controller.Session.Add(CaptchaImage.CaptchaValueKey, " 2222 ");

//act

var registerUserView = new UserView()

{

Email = " user@sample.com",

Password = " 123456",

ConfirmPassword = " 1234567",

AvatarPath = " /file/no-image.jpg",

BirthdateDay = 1,

BirthdateMonth = 12,

BirthdateYear = 1987,

Captcha = " 1111 "

};

 

var result = controller.Register(registerUserView);

Assert.AreEqual(" Текст с картинки введен неверно", controller.ModelState[" Captcha" ].Errors[0].ErrorMessage);

}

Круто?






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.