【发布时间】:2013-04-07 01:27:56
【问题描述】:
我正在探索使用 FluentValidation,因为它似乎是一个优雅的 API,用于在模型绑定时验证我的 ViewModel。我正在寻找有关如何使用此库以及从我的业务(服务)层正确集中验证并将其提升到视图的意见,而无需使用 2 种不同的方法来添加模型状态错误。
我对使用完全不同的 API 持开放态度,但本质上是希望解决这种分支验证策略。
[旁注:我尝试的一件事是将我的业务方法移动到我的 FluentValidation 的自定义 RsvpViewModelValidator 类中并使用 .Must 方法,但在那里隐藏该调用似乎是错误的,因为如果我需要实际使用我的客户对象,他们我将不得不再次重新查询它,因为它超出了范围]
示例代码:
[HttpPost]
public ActionResult AcceptInvitation(RsvpViewModel model)
{
//FluentValidation has happened on my RsvpViewModel already to check that
//RsvpCode is not null or whitespace
if(ModelState.IsValid)
{
//now I want to see if that code matches a customer in my database.
//returns null if not, Customer object if existing
customer = _customerService.GetByRsvpCode(model.RsvpCode);
if(customer == null)
{
//is there a better approach to this? I don't like that I'm
//splitting up the validation but struggling up to come up with a
//better way.
ModelState.AddModelError("RsvpCode",
string.Format("No customer was found for rsvp code {0}",
model.RsvpCode);
return View(model);
}
return this.RedirectToAction(c => c.CustomerDetail());
}
//FluentValidation failed so should just display message about RsvpCode
//being required
return View(model);
}
[HttpGet]
public ActionResult CustomerDetail()
{
//do work. implementation not important for this question.
}
【问题讨论】:
-
您可以将这种决策提取到服务层,但我认为您正在寻找白象。不要将业务/流程逻辑与验证逻辑混淆;一个模型可以是有效的,但它在数据库中没有多大意义。
-
我同意你关于逻辑差异的说法。我想我想知道的是......你认为我上面的代码是正确的还是你会以不同的方式处理事情?我的问题是关于将消息返回到视图以进行验证和业务逻辑的一个广泛开放的“你会做什么”。上面的代码是我能想到的最好的方法。
-
我一直在使用 N-Tier,所以我可能有一个
invitationService.Accept()(或任何可以描述该过程的服务)方法通过/失败,这就是逻辑将被容纳,但没有服务,下一个最佳位置是在控制器内。就个人而言,我会说你在当时的情况下已经做到了最好。 -
好的,我的目标是构建一个能够很好地分离关注点的架构(因此
_customerService)。该代码基于一个示例问题,但我并不局限于此,因为我只是为这个问题编写的。因此,使用您的invitationService.Accept()示例,这将是无效的并引发异常,还是您会从中返回类似IList<Error>的内容以填充ModelState 或其他内容。只是多动一下你的大脑。抱歉,我不是想把它拖出去。 -
如果我介意问答,我不会是这里的常客,所以请走开! - 为了回答你的问题,我会根据方法的作用而反弹。有些返回一个枚举状态(几乎就像成员创建),有些返回一个带有状态码的 int,有些有
out参数,还有一些抛出异常。 (这是我做过的各种一次性项目)。我个人认为拥有一个可以产生验证异常的ProjectNameException基础是更好的方法(通常在 infra/core 库中)。
标签: asp.net-mvc-4 business-logic fluentvalidation modelstate