mvc中的自定义错误处理不起作用

时间:2013-02-28 12:07:43

标签: c# asp.net-mvc asp.net-mvc-3

我在我的控制器中处理错误,我有[CustomErrorHandleAttribute]我已经写了当我的行为中有异常时该怎么办。即使我的代码中没有错误,它也会重定向到customerrorhandle并抛出错误。我无法找到错误的原因。

这是我的代码:

    namespace ExceptionHandlingInMVC.Controllers
    {
    [CustomHandleError]
    public class HomeController : Controller
    {
        //
        // GET: /Home/

        public object Index()
        {
            try
            {
                ViewData["Title"] = "Home Page";
                ViewData["Message"] = "Current time is:" + DateTime.Now.ToLongTimeString();
                var x = 10;
                var y = 10;
                var result = x / y;
                ViewData["Result"] = result;
                return View();
            }
            catch (Exception e)
            {

                throw e;
            }

        }

        [CustomHandleError]
        public object About()
        {
            ViewData["Title"] = "About Page";
            return View();
        }
    }

    public class ErrorPresentation
    {
        public String ErrorMessage { get; set; }
        public Exception TheException { get; set; }
        public Boolean ShowMessage { get; set; }
        public Boolean ShowLink { get; set; }


    }

  }

我写过的CustomHandleErrorAttribute:

    namespace ExceptionHandlingInMVC
   {

    /// <summary>
    /// This attribute (AOP) filter is used to override the Error handling and make sure that all erros are recorded in the event logs, so that they can in turn be picked up by 
    /// our SIEM tool  so that we a) stop customers seing a bad error message and b) we are capturing all the events that happen and c) improives security for 
    /// by preventing a hacker from seing s=details of how our application is put together
    /// </summary>
    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public sealed class CustomHandleErrorAttribute : ActionFilterAttribute
    {
        /// <summary>
        /// This event is called when the action is called i.e. an error has just occured
        /// </summary>
        /// <param name="filterContext"></param>
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            try
            {
                // Bail if we can't do anything; app will crash.
                if (filterContext == null)
                    return;

                // since we're handling this, log to ELMAH(Error logging modules and handler)
                var ex = filterContext.Exception ?? new Exception("No further information exists.");
                WriteToEventLog(ex);

                filterContext.ExceptionHandled = true;
                var data = new ErrorPresentation
                {
                    ErrorMessage = HttpUtility.HtmlEncode(ex.Message),
                    TheException = ex,
                    ShowMessage = filterContext.Exception != null,
                    ShowLink = false
                };

                filterContext.Result = new ViewResult
                {
                    ViewName = "~/Views/Home/ErrorPage.aspx"
                };
            }
            catch (Exception exception)
            {

                throw;
            }

        }

        /// <summary>
        /// This method writes the exception to the event log we have specified in the web.config or the app.config
        /// </summary>
        /// <param name="exception"></param>
        public void WriteToEventLog(Exception exception)
        {
            // pick up which machine we are on, this will already be set for all websites
            var machineName = ConfigurationManager.AppSettings["MachineName"];

            // PIck up the eventlog we are going to write to
            var eventLogName = ConfigurationManager.AppSettings["EventLogName"];

            EventLog.WriteEntry("abc", exception.Message, EventLogEntryType.Error);

        }
    }
}

3 个答案:

答案 0 :(得分:2)

试试这个:

public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        try
        {
            // Bail if we can't do anything; app will crash.
            if (filterContext == null)
                return;

            // since we're handling this, log to ELMAH(Error logging modules and handler)
            if (filterContext.Exception == null || filterContext.ExceptionHandled)
            {
                var ex = filterContext.Exception ?? new Exception("No further information exists.");
                this.WriteToEventLog(ex);
                return;
            };

            filterContext.ExceptionHandled = true;
            var data = new ErrorPresentation
            {
                ErrorMessage = HttpUtility.HtmlEncode(ex.Message),
                TheException = ex,
                ShowMessage = filterContext.Exception != null,
                ShowLink = false
            };

            filterContext.Result = new ViewResult
            {
                ViewName = "~/Views/Home/ErrorPage.aspx"
            };
        }
        catch (Exception exception)
        {

            throw;
        }

    }

如果没有需要返回的exeption,因为这个属性每次都会触发,而不仅仅是在你有错误时。

更新: 我建议你在global.asax中写下面的代码:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new CustomErrorHandle());
    }

解雇所有行动。因此,您无需将属性写入任何操作。

答案 1 :(得分:2)

您应该通过覆盖global.asax中的Application_Error来执行错误处理。这样,您可以确保您的代码仅在发生错误时执行 。使用OnActionExecuted表示您的代码将执行,无论是否抛出错误

这是功能:

void Application_Error(object sender, EventArgs e)
{
    //do your stuff here
}

答案 2 :(得分:0)

当只有错误并且我正在写入事件日志时,应该触发事件:

在我的global.asax中,我添加了以下代码:

    /// <summary>
    /// Managing errors from a single location 
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void Application_Error(object sender, EventArgs e)
    {
        // 1. Get the last error raised
        var error = Server.GetLastError();

        //2. Get the error code to respond with
        var code = (error is HttpException) ? (error as HttpException).GetHttpCode() : 500;

        //3.. Log the error ( I am ignoring 404 error)
        if (code != 404)
        {
            // Write error details to eventlog
            WriteToEventLog(error);
        }

        //4. Clear the response stream
        Response.Clear();

        //5. Clear the server error
        Server.ClearError();

        //6. Render the Error handling controller without a redirect
        string path = Request.Path;
        Context.RewritePath(string.Format("~/Home/Error",code),false);
        IHttpHandler httpHandler = new MvcHttpHandler();
        httpHandler.ProcessRequest(Context);
        Context.RewritePath(path,false);
    }

     /// <summary>
    /// This method writes the exception to the event log we have specified in the web.config or the app.config
    /// </summary>
    /// <param name="exception"></param>
    public void WriteToEventLog(Exception exception)
    {
        EventLog.WriteEntry("abc", exception.Message, EventLogEntryType.Error);
    }