您是否在asp.net mvc应用程序的控制器或业务服务中捕获了预期的异常

时间:2012-07-02 19:02:49

标签: asp.net-mvc exception-handling

我正在开发一个asp.net mvc应用程序,其中user1可以删除之前由user2加载的数据记录。 User2要么更改此不存在的数据记录(Update),要么在另一个违反外键约束的表中插入此数据。

你在哪里捕获这些预期的例外?

在asp.net mvc应用程序的控制器中或业务服务中?

只是一个旁注:如果它的一个ForeignKey约束异常告诉用户另一个用户已删除某个父记录,因此他无法创建测试计划,我只会在这里捕获SqlException。但是这段代码还没有完全实现!

控制器

  public JsonResult CreateTestplan(Testplan testplan)
  {
   bool success = false;
   string error = string.Empty;

   try
  {
   success = testplanService.CreateTestplan(testplan);
   }
  catch (SqlException ex)
   {
   error = ex.Message;
   }
   return Json(new { success = success, error = error }, JsonRequestBehavior.AllowGet);
  }

商业服务:

public Result CreateTestplan(Testplan testplan)
        {
            Result result = new Result();
            try
            {
                using (var con = new SqlConnection(_connectionString))
                using (var trans = new TransactionScope())
                {
                    con.Open();

                    _testplanDataProvider.AddTestplan(testplan);
                    _testplanDataProvider.CreateTeststepsForTestplan(testplan.Id, testplan.TemplateId);
                    trans.Complete();
                    result.Success = true;
                }
            }
            catch (SqlException e)
            {
                result.Error = e.Message;
            }
            return result;
        }

然后在控制器中:

public JsonResult CreateTestplan(Testplan testplan)
      {
       Result result = testplanService.CreateTestplan(testplan);      
       return Json(new { success = result.success, error = result.error }, JsonRequestBehavior.AllowGet);
      }

1 个答案:

答案 0 :(得分:4)

应检查并正确显示外键约束违规。您可以轻松检查相关表中的行是否存在并显示正确的消息。行更新也可以这样做。服务器返回受影响的行数,因此您知道会发生什么。

即使您不进行这些检查,也应该捕获SQL异常。对于普通应用程序用户,有关约束违规的消息不代表任此消息供开发人员使用,您应该使用ELMAH或Log4Net库进行记录。用户应该看到类似于“我们很遗憾的消息。此行可能已被其他用户修改,您的操作已失效。”如果他向开发人员询问它,开发人员应检查日志并查看原因。

修改

我相信你应该检查服务中的错误。控制器不应该知道数据访问层。对于控制器,将数据存储在SQL数据库或文件中无关紧要。文件可以抛出文件访问异常,SQL有其他的。控制器不应该担心它。您可以捕获服务中的数据访问层异常,并使用专用于服务层的类型抛出异常。控制器可以捕获它并显示正确的消息。所以答案是:

public class BusinessService 
{
    public Result CreateTestplan(Testplan testplan)
    {
        Result result = new Result();
        try
        {
            using (var con = new SqlConnection(_connectionString))
            using (var trans = new TransactionScope())
            {
                con.Open();

                _testplanDataProvider.AddTestplan(testplan);
                _testplanDataProvider.CreateTeststepsForTestplan(testplan.Id, testplan.TemplateId);
                trans.Complete();
                result.Success = true;
            }
        }
        catch (SqlException e)
        {
            ....log in ELMAH or Log4Net using other logging framework...
            throw new ServiceException("We are sorry. Your operation conflicted with another operation in database. It has been cancelled.");
        }
        return result;
    }
}