从模型类中捕获异常的最佳方法

时间:2013-08-01 16:06:55

标签: asp.net asp.net-mvc entity-framework

我迷失了我应该在我的asp.net mvc web应用程序中捕获异常的内容/何处/何时。以及如何为最终用户显示错误消息。例如,我得到了以下Action方法: -

    [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(ServerToEdit serverToEdit)
        {
try
        { 
        if (ModelState.IsValid) 
         {
         if (!(repository.IsIPUnique(serverToEdit.TechnologyIP.IPAddress, 0)))
        {
        ModelState.AddModelError("TechnologyIP.IPAddress", "Error occured. The Same IP might already assinged.");

                           return View(serverToEdit);
        }
        if (!(repository.IsServerNameUnique(serverToEdit.Server.Name, 0)))
        {
        ModelState.AddModelError("Server.Name", "Error occured. The Same Server Name might already assinged.");

                           return View(serverToEdit);
                       }
                        repository.InsertOrUpdateServer(serverToEdit.Server,serverToEdit.TechnologyIP,User.Identity.Name);
                        repository.Save();
                        return RedirectToAction("Index");
                    }

        else 
        {
        return View(serverToEdit);
        }
        }
    catch (DbUpdateException)
        {
        ModelState.AddModelError(string.Empty, "Error occured. The Same IP/Name might already assinged.");

        }
    catch (DbEntityValidationException)
                   {
                       ModelState.AddModelError(string.Empty, "Error occured. User might not be defiend inside Active Directory.");

                   }
         return View(serverToEdit);
        }

关于我的代码,我有以下问题: -

  1. 我有两种服务方法(IsIPUnique& IsServeNameUnique);但是Controller操作方法最适合从我的存储库模型类调用这些服务方法吗?

  2. 目前,如果服务方法失败,我手动编写模型状态错误并将视图返回给用户。那么这是为服务方法编写模型状态错误的正确方法吗?

  3. 如果引发了DBUpdateException,我假设数据库中已存在IP或服务名称(如果服务方法无法在高流量应用程序中检查,则可能会发生这种情况)。但是还有许多其他原因导致引发DBUpdateExceptio。所以我的问题是什么是处理DBUpdateException的最佳方法。并准确说明它被提出的原因?

3 个答案:

答案 0 :(得分:2)

控制器通常是进行模型状态验证的正确位置,但是,正如我发现的那样,如果你进行了大量的验证,那么它很容易让控制器膨胀。

我如何处理验证重型控制器方法是将验证导出到服务,比如名为ValidateServer的静态方法(serverToEdit)。

然后在此方法中,运行所有各种检查,并构建一个名为errors的Dictionary,如果检查失败,则向该字典添加错误。

然后,您可以将此字典传递回控制器,并使用foreach将错误添加到ModelState。然后,这将使您只处理异常处理。

为了在DBUpdateException上提供用户信息,您应该能够通过异常.InnerException属性获取有关它的原因的信息,您可以将该属性作为错误消息传递给用户。所以你会写:

catch (DbEntityValidationException ex)
               {
                   ModelState.AddModelError(string.Empty, "Error occurred:" + ex.InnerException);

               }

或者其他类似的东西!

答案 1 :(得分:2)

不要将验证与异常处理混合在一起。

在一个集中位置处理异常更有意义,并向最终用户记录和显示错误。这样,您就可以使代码更具可读性和可维护性。 CodeProject对此主题有a great article

答案 2 :(得分:1)

我认为你可以添加另一个包装调用的层,并以某种状态和错误(如果有的话)返回结果,并在返回消息失败的情况下使用modelstate,这样你的控制器就会更具可读性。