【问题标题】:ASP.NET MVC, solution for transfering validation messages from service layer validation to view modelASP.NET MVC,将验证消息从服务层验证传输到视图模型的解决方案
【发布时间】:2013-09-05 11:08:54
【问题描述】:

MVC 使用 DataAnnotations 属性的内置模型验证效果很好,并且大大加快了开发速度。然而,在许多情况下,应用程序的表示层无法处理验证,例如检查数据库中已存在的唯一属性值。

我正在寻找满足以下要求的此问题的解决方案:

  • 与 NInject(和其他 DI 方法)兼容。
  • 不会破坏 SoC。服务层必须完全不知道表示层。
  • 是自动的。在(至少)表示层中产生最少的额外代码。想想[ValidateServiceLayer] 的操作方法。
  • 坚持DRY原则。最少的代码复制。
  • 将验证消息分配给正确的属性(在需要时)。
  • 允许在运行之前和之后添加其他验证消息。

这些功能的加分项:

  • 优雅地捕获异常并显示用户友好的错误消息。
  • 易于使用。 (NuGet 包?)

我对如何自己实现这一点有一些想法,但在我开始发明轮子之前,我想知道它是否已经被其他人完善了。有人遇到过这种情况吗?

【问题讨论】:

标签: c# asp.net-mvc validation asp.net-mvc-4


【解决方案1】:

您当然可以使用 RemoteAttribute,这是一个合法的解决方案,但我有时会选择不同的方法。我不确定这是不是最好的解决方案,但它对我来说很有效,我认为它可能值得一提。

我的每个模型类都继承自如下所示的基本模型:

public abstract class BaseModel
{
   private ModelStateDictionary _modelState = new ModelStateDictionary();
   public ModelStateDictionary ModelState
   {
      get
      {
         return _modelState;
      }
      set
      {
         _modelState = value;
      }
   }
}

这样在我的控制器中我可以执行以下操作:

[HttpPost]
public ActionResult EditUser(user model)
{
   if (ModelState.IsValid)
   {
       model.ModelState = ModelState;
       _userService.Update(model);
   }
   if (ModelState.IsValid)
   {
       // Edit user was successful - No validation issues in business logic.
       return View("Users"); 
   }
   return View(model);
}

因此,由于我们将 ModelState 作为属性添加到您的所有模型中,您现在可以通过模型实例在服务逻辑中对其进行操作。例如,如果您的服务中出现验证问题,您可以这样做:

model.ModelState.AddModelError("Property Name", "Error Text");

这里唯一的开销是在控制器操作中检查 ModelState.IsValid 两次,一次在调用服务之前,一次在调用之后。

就像我说的,我不确定这是否完美,但它对我们有用。由您决定什么最适合您。

注意:您必须将 System.Web.Mvc 程序集的引用添加到您的服务层,因为 ModelStateDictionary 类驻留在其中,但我认为这不是问题。

【讨论】:

  • 谢谢。总的来说,这似乎是一个很好的方法,但在我的情况下,服务不应该与我的视图模型接触,我的视图模型是我们解决方案中表示层的一部分。
  • @NicklasForss 该服务根本不需要与您的视图模型联系。我假设您有某种方法可以通过 AutoMapper 将视图模型转换为域模型?如果是这样,那么 ModelState 也将像任何其他属性一样映射...
  • @NicklasForss 更好地让您的域模型从包含 ModelState 属性的基本模型继承,然后一旦您将视图模型映射到您的域模型,然后只需将 ModelState 附加到它。实际上是多了 1 行代码...
【解决方案2】:

ASP.NET MVC 提供了一种机制,可以进行远程服务器调用以验证表单字段,而无需将整个表单发布到服务器。该机制称为远程验证

请看:http://msdn.microsoft.com/en-us/library/gg508808(v=vs.98).aspx

【讨论】:

  • RemoteAttribute 似乎可以满足要求。不过,我对它工作所需的所有“魔术字符串”感到有些厌烦。
猜你喜欢
  • 2010-11-18
  • 1970-01-01
  • 2012-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多