Я разрабатываю многоуровневое веб-приложение со слоем MVC, Service и Repository, однако мне сложно понять, где разместить логику проверки, которая позволяет мне использовать преимущества встроенной проверки формы .NET Core (например, ModelStateDictionary
), следуя принципу СУХОЙ.
first и наиболее очевидный подход заключается в использовании ViewModel
, который имеет соответствующие аннотации данных:
public class VendorViewModel
{
public long Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Phone { get; set; }
[Required]
public string Email { get; set; }
[Required]
public string Address { get; set; }
public DateTime? VerifiedAt { get; set; }
}
Тогда действие моего контроллера будет выглядеть так:
public async Task<IActionResult> Create([FromForm] VendorViewModel model)
{
await AuthorizePolicyAsync(AuthorizationPolicyTypes.Vendor.Create);
if (!ModelState.IsValid) //Validation problems, so re-display the form.
return View(model);
await _vendorservice.CreateVendorAsync(model.Name,model.Phone,model.Email,model.Address,null);
return RedirectToAction(nameof(Index));
}
Это работает нормально, однако есть пара проблем:
- Это поддерживает только базовую проверку, такую как проверка длины символа и т. Д.В приведенном выше конкретном примере я хочу проверить, что
model.Address
является действительным адресом в соответствии с картами Google, а также содержит город, о котором известно приложению, что означает, что этот вид проверки должен быть перемещен на уровень обслуживания, чтобы сохранитьКонтроллер "тонкий". - На уровне сервиса теперь отсутствует какая-либо логика проверки и предполагается, что он всегданг передал действительные данные.Мне кажется, что это неправильно, поскольку уровень обслуживания должен отвечать за поддержание системы в согласованном действительном состоянии.Решением этой проблемы было бы также добавить логику проверки к уровню обслуживания, но, по моему мнению, это нарушает принцип DRY.
Подход second заключается в перемещениивсю логику проверки на сервисном уровне и переместить все мои аннотации данных в фактический объект домена Vendor
.Таким образом, каждая операция может проверять модель на основе аннотаций данных, а также применять более сложную логику, такую как проверка адреса с помощью карт Google, как упоминалось ранее.Однако я не уверен, как я могу проверить аннотированный объект таким же образом, как это делает MVC Controller
, и передать обратно словарь в контроллер.Эта функциональность, по-видимому, специфична для MVC и привнесет зависимость от MVC на моем уровне обслуживания, что нежелательно.
В любом случае я могу элегантно перенести логику проверки на уровень обслуживания, используя преимущества аннотаций данных и MVCвстроенный ModelStateDictionary
?Как мне вернуть список ошибок обратно в контроллер?Выдать ли исключение и перехватить его в контроллере, если возникнут какие-либо ошибки проверки?
Я видел несколько вопросов, задающих аналогичный вопрос, но я не удовлетворен ни одним из ответов.Другие ответы, похоже, предполагают написание логики проверки вручную и не используют аннотации данных.Это то, к чему я должен прибегнуть?