Сървърна проверка на потребителските данни

public void Val >низ потребителско име, низ потребителска парола) < ако ( /*проверете потребителското име*/) изхвърлете ново InvalidUsernameException(); ако ( /*проверете паролата*/) изхвърлете ново InvalidPasswordException(); >

public void RegisterUser (низ потребителско име, низ парола) опитайте ValidateUser(потребителско име, парола); >

catch (InvalidUsernameException ex) //добавяне към колекция от грешки >

catch (InvalidPasswordException ex) //добавяне към колекция от грешки >

Какво не е наред с този пример?- Използват се изключения по време на бизнес валидирането. Важно е да запомните, че грешки при валидиране на данни != грешки в приложението; —използването на изключения по време на фазата на бизнес валидиране може да доведе до срив на приложението. Това може да се случи, например, ако човек забрави да напише друг catch блок за нови правила за валидиране; - кодът изглежда грозен; - такова решение е трудно за тестване и поддръжка.

публичен клас ValidationResult private bool isSucceedResult = true; private readonly List resultCodes = new List();

public ValidationResult(Код на резултатния код) isSucceedResult = false; resultCodes.Add(код); >

public static ValidationResult SuccessResult get < върне нов резултат от проверката (); > >

public void AddError(код на резултатния код) isSucceedResult = false; resultCodes.Add(код); >

public void Merge(ValidationResult result) resultCodes.AddRange(result.resultCodes); isSucceedResult &= result.isSucceedResult; > >

публичен абстрактен клас Validator публичен абстрактен ValidationResult Validate(); >

Валидаторните обекти имат 1 метод, който стартира процедурата за валидиране и се връщарезултат.

CompositeValidatorе клас, съдържащ колекция от валидатори и стартиращ механизъм за валидиране за всички дъщерни обекти:

публичен клас CompositeValidator : Валидатор частен само за четене List val >new List();

public void Add(Validator validator) validators.Add(validator); >

public void Премахни(валидатор валидатор) validators.Remove(валидатор); >

публична замяна ValidationResult Validate() Val > foreach (Val >in validators) result.Merge(validator.Validate()); > връща резултат; > >

Използвайки тези класове, успяхме да създадем валидатори с определени правила, да ги комбинираме и да получим резултати от валидирането.

публичен клас UserNameValidator: Валидатор частен низ само за четене userName;

public UserNameVal >string userName) това .userName= потребителско име; >

public override ValidationResult Validate() if ( /*параметърът не е преминал проверката на условието, например userName = null*/ ) върне нов ValidationResult(ResultCode.UserNameIncorrect); >

По същия начин получавамеUserPasswordValidator.

Сега имаме всичко, за да използваме новия механизъм за валидиране на данни:

public ValidationResult Val >низ потребителско име, низ потребителска парола) CompositeVal >нов CompositeValidator(); val >new UserNameValidator(userName)); val >нов UserPasswordValidator(userPassword));

public void RegisterUser ( низ потребителско име, низ парола) Val > if (result.IsSucceed) //успешно валидиране >

else //получаване на резултат от грешки при проверка.GetResultCodes() и обработка по съответния начин >

Какви ползи получихме, като използвахме този подход:- разширяемост. Добавянето на нови валидатори е евтино; — възможност за тестване. Всички валидатори могат да бъдат единично тествани, което елиминира наличието на грешки в цялостния процес на валидиране; — поддръжка. Валидаторите могат да бъдат отделени в отделна сборка и използвани в много проекти с малки промени; — красота и коректност. Този код изглежда по-красив, по-елегантен и по-правилен от оригиналната версия, изключения не се използват за бизнес валидиране.

Заключение

Моля, не ритайте много за възможни грешки в писането и представянето. Много се постарах) С удоволствие ще изслушам критики и предложения относно изпълнението и архитектурата.

И тук можете да получите грант за тестов период на Yandex.Cloud. Необходимо е само да въведете "Habr" в полето "секретна парола".