2013-02-28 81 views
2

我处理我的控制器错误,我有[CustomErrorHandleAttribute]这是我写的时候没有在我的行动异常做什么处理。即使在我的代码中没有错误,它将重定向到errorrorhandle并抛出错误。我无法找到错误的原因。自定义错误MVC中不工作

这里是我的代码:

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); 

     } 
    } 
} 
+0

你并不真的需要创建自己的属性,只需覆盖'Application_Error'在Global.asax的,把你的自定义日志记录代码在那里。 – mattytommo 2013-02-28 12:29:36

+1

但是为了帮助你,我会打赌,属性不甚至被解雇的错误,因为你已经overrided'OnActionExecuted',这将不会在错误点发生。 – mattytommo 2013-02-28 12:30:18

+0

@mattytommo我现在不重写我的代码工作时,有没有错误,我的错误处理时出现错误 – 62071072SP 2013-02-28 12:39:27

回答

2

你确实应该进行错误处理在global.asax中覆盖Application_Error。这样,您可以确保您的代码只会在发生错误时执行。使用OnActionExecuted意味着你的代码将执行不管或无论是否引发错误

这里的功能:

void Application_Error(object sender, EventArgs e) 
{ 
    //do your stuff here 
} 
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()); 
    } 

这个attibute火到所有动作。所以你不需要为任何动作写属性。

+0

谢谢你的工作 – 62071072SP 2013-02-28 13:02:33

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); 
    }