微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

asp.net-mvc – ASP.Net MVC异常记录与错误处理相结合

我在ASP.Net MVC 1.0应用程序中寻找一个简单的解决方案来执行异常记录和错误处理。

我读过很多文章包括StackOverflow上发布的问题,这些都为不同情况提供了不同的解决方案。我仍然无法提出一个适合我需要的解决方案。

这是我的要求:

>为了能够在我的Controller上使用[HandleError]属性(或者相当于某些东西)来处理可以从任何动作或视图抛出的所有异常。这应该处理在任何操作上没有特别处理的所有异常(如第2点所述)。我想指定哪个View用户必须重定向错误的情况下,对于Controller中的所有操作。
>我希望能够指定具体操作顶部的[HandleError]属性(或等效的)来捕获特定的异常并将用户重定向到适用于异常的视图。所有其他异常仍然必须由Controller上的[HandleError]属性来处理。
>在上述两种情况下,我想使用log4net(或任何其他日志记录库)记录异常。

如何实现上述目标?我已经阅读了关于使我所有的控制器继承自一个基本控制器,它覆盖了OnException方法,其中我做了我的日志记录。但是,这会让用户重定向到相应的视图,或使其变得混乱。

我已经阅读过关于编写我自己的Filter Action,它实现了IExceptionFilter来处理这个问题,但这会与[HandleError]属性冲突。

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

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

上述代码是否符合我的要求?如果没有,什么解决方案能够满足我的要求?

解决方法

我仍然对所有不同的解决方案感到困惑,而且属性如何可以相互干扰,但是我已经解决了这个问题:
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]属性来装饰每个控制器。

这对我来说是有效的,因为它将错误日志记录保存在一个地方,并且不会导致重复的异常被多次记录(如果我扩展[HandleError]并在多个地方使用该属性将会发生)。

我不认为将异常记录和错误处理结合到一个属性或类中是不可能的,而不会变得非常繁琐和复杂,或者影响使用[HandleError]

但是这对我来说是有用的,因为我仅使用[LogErrors]属性来装饰每个控制器一次,并且使用[HandleError]精确地装饰控制器和操作,而不会彼此干扰。

更新:

以下是我如何使用它的示例:

[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"; } }

    }
}

在上述代码中,ContactForm操作重载中的SmtpExceptions以非常特定的方式进行处理 – 用户会看到特定于发送失败消息的ViewPage,在这种情况下它被称为“MessageFailed”。所有其他异常都由[HandleError]的认行为来处理。另请注意,首先记录错误,然后处理错误。这由以下指示:

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

更新:

一个替代解决方案,具有非常好的解释。我建议您阅读它,以便更好地了解所涉及的问题。

ASP.NET MVC HandleError Attribute,Custom Error Pages and Logging Exceptions(感谢下面的Scott Shepherd,谁在下面的答案中提供了链接)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


这篇文章主要讲解了“WPF如何实现带筛选功能的DataGrid”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“WPF...
本篇内容介绍了“基于WPF如何实现3D画廊动画效果”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这...
Some samples are below for ASP.Net web form controls:(from http://www.visualize.uk.com/resources/asp
问题描述: 对于未定义为 System.String 的列,唯一有效的值是(引发异常)。 For columns not defined as System.String, the only vali
最近用到了CalendarExtender,结果不知道为什么发生了错位,如图在Google和百度上找了很久,中文的文章里面似乎只提到了如何本地化(就是显示中文的月份)以及怎么解决被下拉框挡住的问题,谈
ASP.NET 2.0 page lifecyle ASP.NET 2.0 event sequence changed a lot since 1.1. Here is the order: App
静态声明: ' Style="position: relative" AppendDataBoundItems="True"> (无 或 空 或
以下内容是从网络上搜集资料,然后整理而来的。不当之处,请不吝指教。(The following were from network, and edited by myself. Thanks in a
Imports System Imports System.Reflection Namespace DotNetNuke '*********************************
Ok so you have all seen them: “8 million tools for web development”, “5 gagillion tools that if you