ASP.Net MVC异常日志记录与错误处理相结合 [英] ASP.Net MVC Exception Logging combined with Error Handling

查看:130
本文介绍了ASP.Net MVC异常日志记录与错误处理相结合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要寻找一个简单的解决方案做的异常记录,错误在我的ASP.Net MVC 1.0应用程序中处理相结合。

I am looking for a simple solution to do Exception Logging combined with Error Handling in my ASP.Net MVC 1.0 application.

我读过很多文章,包括在这里张贴计算器的问题,这都提供了不同的情况不同的解决方案。我仍然无法拿出一个适合我的需求的解决方案。

I've read lots of articles, including Questions posted here on StackOverflow, which all provide varying solutions for different situations. I am still unable to come up with a solution that suits my needs.

下面是我的要求:


  1. 要能够在我的控制器使用[的HandleError]属性(或等值的东西),以处理可能从任何操作或视图抛出的所有异常。这应该处理了(如第2点所述)没有特别的任何动作的处理所有异常。我希望能够指定查看用户必须错误的情况下被重定向到,在控制器的所有操作。

  1. To be able to use the [HandleError] attribute (or something equivalent) on my Controller, to handle all exceptions that could be thrown from any of the Actions or Views. This should handle all exceptions that were not handled specifically on any of the Actions (as described in point 2). I would like to be able to specify which View a user must be redirected to in error cases, for all actions in the Controller.

我希望能够指定特定动作的顶部[的HandleError]属性(或等值的东西),捕获特定的异常和用户重定向到适当的异常的视图。所有其它的异常必须仍然控制器上的[的HandleError]属性来处理。

I want to be able to specify the [HandleError] attribute (or something equivalent) at the top of specific Actions to catch specific exceptions and redirect users to a View appropriate to the exception. All other exceptions must still be handled by the [HandleError] attribute on the Controller.

在上述两种情况下,我想用log4net的(或任何其他日志库)要记录的异常。

In both cases above, I want the exceptions to be logged using log4net (or any other logging library).

我如何去实现上面?我读过有关让我所有的控制器从基本控制器,覆盖onException的方法继承,而其中我做我的记录。然而,这会搞乱与周围将用户重定向到相应的视图,或者使杂乱。

How do I go about achieving the above? I've read about making all my Controllers inherit from a base controller which overrides the OnException method, and wherein I do my logging. However this will mess around with redirecting users to the appropriate Views, or make it messy.

我读过有关编写它实现个IExceptionFilter来处理这个我自己的筛选器操作,但这将与[的HandleError]属性冲突。

I've read about writing my own Filter Action which implements IExceptionFilter to handle this, but this will conflict with the [HandleError] attribute.

到目前为止,我的想法是,最好的解决办法就是写我自己的属性,从HandleErrorAttribute继承。这样,我得到的[的HandleError]所有功能,并且可以添加自己的log4net的日志记录。该解决方案如下:

So far, my thoughts are that the best solution is to write my own attribute that inherits from HandleErrorAttribute. That way I get all the functionality of [HandleError], and can add my own log4net logging. The solution is as follows:

    public class HandleErrorsAttribute: HandleErrorAttribute {

      private log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

      public override void OnException(ExceptionContext filterContext)
      {
          if (filterContext.Exception != null)
          {
            log.Error("Error in Controller", filterContext.Exception);
          }

          base.OnException(filterContext);
      }
   }

请问我的要求,上述code的工作?如果不是,有什么解决方案并满足我的要求吗?

Will the above code work for my requirements? If not, what solution does fulfill my requirements?

推荐答案

我还是有点糊涂了所有不同的解决方案在那里,以及如何属性可以互相干扰,但我用这个解决方案去:

I'm still a bit confused with all the different solutions out there, and how attributes can interfere with each other, but I went with this solution:

public class LogErrorsAttribute: FilterAttribute, IExceptionFilter
{
    #region IExceptionFilter Members

    void IExceptionFilter.OnException(ExceptionContext filterContext)
    {
        if (filterContext != null && filterContext.Exception != null)
        {
            string controller = filterContext.RouteData.Values["controller"].ToString();
            string action = filterContext.RouteData.Values["action"].ToString();
            string loggerName = string.Format("{0}Controller.{1}", controller, action);

            log4net.LogManager.GetLogger(loggerName).Error(string.Empty, filterContext.Exception);
        }

    }

    #endregion
}

我还是用[的HandleError]属性为原来的问题解释说,我只是装饰用[LogErrors]属性的每个控制器。

I still use the [HandleError] attribute as explained in the original question, and I just decorate each controller with a [LogErrors] attribute.

这对我的作品,因为它使错误记录在一个地方,不会造成重复异常被多次记录(如果我延长[的HandleError]并使用在多个地方属性,它会发生)。

This works for me, as it keeps the error logging in one place and doesn't cause duplicate exceptions to be logged multiple times (which will happen if I extend [HandleError] and use the attribute in multiple places).

我不认为这将有可能两个异常记录和错误处理成一个atrribute或类相结合,没有它变得非常繁琐和复杂,或影响使用[的HandleError]

I don't think it will be possible to combine both the Exception Logging and Error Handling into one atrribute or class, without it becoming very tedious and complex, or affecting the use of [HandleError]

但是,这对我的作品,因为我装点每个控制器只有一次,用[LogErrors]属性,和装饰控制器和行动[的HandleError]我到底想,没有他们彼此。

But this works for me since I decorate each controller only once, with the [LogErrors] attribute, and decorate Controllers and Actions with [HandleError] exactly how I want to, without them interfering with each other.

更新:

下面是如何使用它的一个例子:

Here is an example of How I use it:

[LogErrors(Order = 0)]
[HandleError(Order = 99)]
public class ContactController : Controller
{
    public ActionResult Index()
    {
        return View(Views.Index);
    }

    public ActionResult Directions()
    {
        return View(Views.Directions);
    }


    public ActionResult ContactForm()
    {
        FormContactMessage formContactMessage = new FormContactMessage();

        return View(Views.ContactForm,formContactMessage);
    }

    [HandleError(ExceptionType = typeof(SmtpException), View = "MessageFailed", Order = 1)]
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult ContactForm(FormContactMessage formContactMessage)
    {
        if (ModelState.IsValid)
        {
            if (formContactMessage.IsValid)
            {
                SmtpClient client = new SmtpClient();

                MailAddress recipientAddress = new MailAddress(Properties.Settings.Default.ContactFormRecipientEmailAddress);
                MailAddress senderAddress = new MailAddress(Properties.Settings.Default.ContactFormSenderEmailAddress);
                MailMessage mailMessage = formContactMessage.ToMailMessage(recipientAddress, senderAddress);

                client.Send(mailMessage);

                return View("MessageSent");
            }
            else
            {
                ModelState.AddRuleViolations(formContactMessage.GetRuleViolations());
            }
        }
        return View(Views.ContactForm, formContactMessage);
    }

    private static class Views
    {
        public static string Index { get { return "Index"; } }
        public static string Directions { get { return "Directions"; } }
        public static string ContactForm { get { return "ContactForm"; } }

    }
}

在上面的code,在的ContactForm 行动超载SmtpExceptions在一个非常特殊的方式处理 - 用户用的ViewPage具体到psented $ P $失败发送的消息,在这种情况下,它被称为MessageFailed。所有其他异常,通过[的HandleError]默认的行为进行处理。还要注意的是错误的记录发生第一,其次是处理错误的。这是由以下表示:

In the above code, SmtpExceptions in the ContactForm action overload are handled in a very specific way - the user is presented with a ViewPage specific to failed sent messages, in this case it is called "MessageFailed" . All other exceptions are handled by the default behaviour of [HandleError]. Also note that logging of errors occurs first, followed by handling of errors. This is indicated by the following:

[LogErrors(Order = 0)]
[HandleError(Order = 99)]

更新:

有一种替代解决方案,这一点,具有非常好的explanantion。我建议通过阅读它,以获得更好的了解所涉及的问题。

There is an alternative solution to this, with a very good explanantion. I recommend reading through it to get a better understanding of the issues involved.

ASP.NET MVC的HandleError属性,自定义错误页和日志例外
(感谢斯科特以下牧羊人,谁的答案提供下面的链接)。

ASP.NET MVC HandleError Attribute, Custom Error Pages and Logging Exceptions (Thanks to Scott Shepherd below, who provided the link in an answer below).

这篇关于ASP.Net MVC异常日志记录与错误处理相结合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆