Мне определенно не нравится это дополнение в версии 2.0, потому что, как вы указали в своем вопросе, проверка имеет больше смысла в слое Service. Таким образом, вы можете повторно использовать его в других не-веб-приложениях и тестировать его проще, не издеваясь над механизмом автоматической проверки.
Проверка на уровне контроллера не имеет смысла, поскольку в этой части вы можете проверять только данные модели, а не бизнес-правила. Например, подумайте о службе, ответственной за добавление новых комментариев, и о пользователе, который хочет опубликовать новый, данные в комментарии, которые он / она публикует, могут быть действительными, но что произойдет, если пользователю запретят комментировать из-за неправильного поведения в прошлом? Вы должны выполнить некоторую проверку на уровне Service, чтобы убедиться, что этого не происходит, и, если это произойдет, выдать исключение. Короче говоря, проверка должна выполняться на уровне службы.
Я использую xVal в качестве моей инфраструктуры валидации, потому что она совместима с DataAnnotationModel, позволяет размещать валидацию там, где я хочу, и выполняет валидацию на стороне клиента без лишних усилий, даже на стороне удаленного клиента. Вот как я использую его в начале каждого из моих сервисов, например, сервис входа в систему:
public void SignIn(Login login) {
var loginErrors = DataAnnotationsValidationRunner.GetErrors(login);
// Model validation: Empty fields?
if (loginErrors.Any())
throw new RulesException(loginErrors);
// Business validation: Does the user exist? Is the password correct?
var user = this._userRepository.GetUserByEmail(login.Email);
if (user == null || user.Password != login.Password)
throw new RulesException(null, "Username or password invalids");
// Other login stuff...
}
Простой, независимый от сети и легкий ... затем в контроллере:
public RedirectResult Login(Login login) {
// Login the user
try {
this._authenticationRepository.SignIn(login);
} catch (RulesException e) {
e.AddModelStateErrors(base.ModelState, "Login");
}
// Redirect
if (base.ModelState.IsValid)
return base.Redirect(base.Url.Action("Home"));
else return base.Redirect(base.Url.Action("Login"));
}