MVC3我应该捕捉到什么级别的错误

时间:2012-02-06 15:46:43

标签: asp.net-mvc-3 entity-framework try-catch

我有一个使用MVC3的网站。我有一个n层架构,我很好奇在什么级别最好捕获错误。

对于isntance,假设我有一个Students表,我有一个StudentRepository,其函数如下: StudentRepository.GetHightestGrade(studentId)

所以我应该让我的Repositry函数有一个try / catch块 - 或者我应该将try / catch直接放入ActionResult函数中。或者我会更好地添加到业务类中,然后我的ActionResult函数会执行诸如

之类的操作

Business.GetHighestGrade(studentId)和该函数只是有一个try / catch并调用Repository函数?

4 个答案:

答案 0 :(得分:1)

这取决于你想要捕获的内容,你是否只想默默地失败?你想记录错误吗?你想返回一个视图来通知用户出了什么问题吗?

如果您只想通知用户,请在控制器中捕获它。 如果你想记录它,然后在你的仓库中捕获它,并让你的repo通过一些日志服务进行日志记录,你可以使用一些更高级的服务来执行调用捕获错误并记录它,但这可能是一个过度杀死。

答案 1 :(得分:1)

如果你试图阻止错误冒泡堆栈,你应该只在try / catch中包装方法。通常,最好将try / catch放在顶层,以保护用户免受错误的影响。在特殊情况下,较低层通常应抛出异常,您应该只尝试在较高层捕获它们。

你会发现你的代码在没有大量try / catch块的情况下更具可读性,我个人尽量避免使用它们,并让MVC3 HandleError过滤器属性负责显示错误消息。但是,有时您可能希望在它抛出异常时重试一个操作,这会成为一个很好的try / catch候选者。

看一下ELMAH - 使用它可以帮助你编写代码,避免出现异常。但是,如果您期望异常,则应该只显式尝试/ catch,并且希望采取一些操作来响应它。

答案 2 :(得分:0)

您应该为自定义异常编写全局过滤器属性。捕获该过滤器上的所有异常并返回视图。像这样的东西

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.Text;

    namespace Filters
    {
        public sealed class HandleException : FilterAttribute, IExceptionFilter
        {
            public void OnException(ExceptionContext filterContext)
            {
                if (filterContext == null)
                    throw new ArgumentException("filterContext");
                else if (typeof(AjaxException).IsInstanceOfType(filterContext.Exception) && !filterContext.ExceptionHandled)
            {
                filterContext.ExceptionHandled = true;
                filterContext.HttpContext.Response.Clear();
                filterContext.HttpContext.Response.ContentEncoding = Encoding.UTF8;
                filterContext.HttpContext.Response.HeaderEncoding = Encoding.UTF8;
                filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
                filterContext.HttpContext.Response.StatusCode = 400;
                filterContext.Result = new ContentResult
                {
                    Content = "Unexpected error",
                    ContentEncoding = Encoding.UTF8,
                };
            }
        }
    }
}

并将此过滤器添加到global.asax

中的全局过滤器属性

答案 3 :(得分:0)

存储库级别必须具有处理sql异常并将错误写入Log的try-catch构造。如果您的业务逻辑很复杂并且可能产生错误或不一致的状态 - 您应该检查它并将错误写入Log。如果您想通知用户有关错误的事情(如果业务逻辑提供例外) - 您应该在控制器操作中使用try-catch构造并使用ModelState.AddModelError()作为通知用户的方法之一,或使用其他方式将有关错误的信息传递给视图。最后,必须在Application_Start中的global.asax中注册class CustomErrorFilter : IExceptionFilter

GlobalFilters.Filters.Add(new LoggingFilter());

该过滤器应写入记录控制器级别上发生的所有未处理错误。

请记住,您的代码提供了正常的工作流程,并且可以提供错误工作流程(将异常作为组织错误工作流程的方法之一,或返回一些错误代码)。你应该指望它并处理两个工作流程。