【发布时间】:2018-10-25 13:18:51
【问题描述】:
我正在设计一个带有 MVC、Service 和 Repository 层的分层 Web 应用程序,但是我不知道在哪里放置允许我利用 .NET Core 内置表单验证的验证逻辑(例如 @987654321 @),同时遵循 DRY 原则。
第一个也是最明显的方法是使用具有适当数据注释的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是根据谷歌地图的有效地址,并且还包含应用程序知道的城市,这意味着应该将这种验证移至服务层以保持控制器“瘦”。 - 服务层现在缺少任何验证逻辑,并假定它始终被传递有效数据。这对我来说似乎是错误的,因为服务层似乎应该负责使系统保持一致的有效状态。解决这个问题的方法是向服务层添加验证逻辑,但我认为这似乎违反了 DRY 原则。
第二种方法是将所有验证逻辑移动到服务层,并将我的所有数据注释移动到实际的域对象Vendor。这样,每个操作都可以根据数据注释验证模型,还可以应用任何更复杂的逻辑,例如使用谷歌地图验证地址,如前所述。但是,我不确定如何以与 MVC Controller 相同的方式验证带注释的对象并将字典传回控制器。此功能似乎特定于 MVC,并且会在我的服务层中引入对 MVC 的依赖,这是不可取的。
无论如何我可以优雅地将验证逻辑移动到服务层,同时
利用 ModelStateDictionary 内置的数据注释和 MVC?如何将错误列表返回给控制器?如果发生任何验证错误,我是否会抛出异常并在控制器中捕获它?
我看到几个问题提出了类似的问题,但我对任何答案都不满意。其他答案似乎涉及手动编写验证逻辑而不利用数据注释。这是我应该求助的吗?
【问题讨论】:
-
嗨布拉德,你得到了正确的回应吗?
标签: c# asp.net-mvc validation asp.net-core