2

私は自分のコントローラーでエラーを処理して[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);

        }
    }
}
4

3 に答える 3

2

Application_Errorglobal.asaxでオーバーライドして、実際にエラー処理を実行する必要があります。そうすれば、エラーが発生したときにのみコードが実行されることを確認できます。を使用するということは、エラーがスローされるかどうかに関係なくOnActionExecuted、コードが実行されることを意味します。

関数は次のとおりです。

void Application_Error(object sender, EventArgs e)
{
    //do your stuff here
}
于 2013-02-28T16:02:31.717 に答える
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;
        }

    }

この属性は、エラーが発生したときだけでなく、毎回発生するため、返す必要がある例外がない場合。

更新: global.asax に以下のコードを記述することをお勧めします。

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

この属性をすべてのアクションに適用します。したがって、どのアクションにも属性を書き込む必要はありません。

于 2013-02-28T12:53:00.850 に答える
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);
    }
于 2013-02-28T15:57:22.743 に答える