在ASP.NET MVC中logging错误
我目前在我的ASP.NET MVC应用程序中使用log4net来loggingexception。 我这样做的方式是让我所有的控制器都inheritance自一个BaseController类。 在BaseController的OnActionExecuting事件中,我logging了可能发生的任何exception:
protected override void OnActionExecuted(ActionExecutedContext filterContext) { // Log any exceptions ILog log = LogManager.GetLogger(filterContext.Controller.GetType()); if (filterContext.Exception != null) { log.Error("Unhandled exception: " + filterContext.Exception.Message + ". Stack trace: " + filterContext.Exception.StackTrace, filterContext.Exception); } }
如果在控制器操作期间发生未处理的exception,这非常有效。
至于404错误,我有我的web.config中设置自定义错误,如下所示:
<customErrors mode="On"> <error statusCode="404" redirect="~/page-not-found"/> </customErrors>
而在处理“页面未find”url的控制器操作中,我logging了请求的原始URL:
[AcceptVerbs(HttpVerbs.Get)] public ActionResult PageNotFound() { log.Warn("404 page not found - " + Utils.SafeString(Request.QueryString["aspxerrorpath"])); return View(); }
这也是有效的。
我遇到的问题是如何logging.aspx页面上的错误。 假设我在其中一个页面上有一个编译错误,或者一些内联代码会抛出一个exception:
<% ThisIsNotAValidFunction(); %> <% throw new Exception("help!"); %>
看来,HandleError属性正确地重新路由到我的Error.aspx共享文件夹中的页面,但它肯定不会被我的BaseController的OnActionExecuted方法捕获。 我想我也许可以将日志logging代码放在Error.aspx页面上,但我不确定如何检索该级别的错误信息。
我会考虑通过插入Elmah来简化您的Web应用程序。
您将Elmah程序集添加到您的项目,然后configuration您的web.config。 然后它将logging在控制器或页面级创build的exception。 它可以configuration为login到各种不同的地方(如SQL Server,电子邮件等)。 它还提供了Web前端,以便您浏览exception日志。
它是我添加到我创build的任何asp.net mvc应用程序的第一件事。
我仍然使用log4net,但是我倾向于使用它来loggingdebugging/信息,并将所有exception保留给Elmah。
您也可以在问题中find更多信息如何在ASP.NET应用程序中logging错误(exception)? 。
您可以钩入Global.asax中的OnError事件。
像这样的东西:
/// <summary> /// Handles the Error event of the Application control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> protected void Application_Error(object sender, EventArgs e) { if (Server != null) { Exception ex = Server.GetLastError(); if (Response.StatusCode != 404 ) { Logging.Error("Caught in Global.asax", ex); } } }
MVC3
创build从HandleErrorInfoAttributeinheritance的属性,并包括您select的日志logging
public class ErrorLoggerAttribute : HandleErrorAttribute { public override void OnException(ExceptionContext filterContext) { LogError(filterContext); base.OnException(filterContext); } public void LogError(ExceptionContext filterContext) { // You could use any logging approach here StringBuilder builder = new StringBuilder(); builder .AppendLine("----------") .AppendLine(DateTime.Now.ToString()) .AppendFormat("Source:\t{0}", filterContext.Exception.Source) .AppendLine() .AppendFormat("Target:\t{0}", filterContext.Exception.TargetSite) .AppendLine() .AppendFormat("Type:\t{0}", filterContext.Exception.GetType().Name) .AppendLine() .AppendFormat("Message:\t{0}", filterContext.Exception.Message) .AppendLine() .AppendFormat("Stack:\t{0}", filterContext.Exception.StackTrace) .AppendLine(); string filePath = filterContext.HttpContext.Server.MapPath("~/App_Data/Error.log"); using(StreamWriter writer = File.AppendText(filePath)) { writer.Write(builder.ToString()); writer.Flush(); } }
在Global.asax RegisterGlobalFilters中放置属性
public static void RegisterGlobalFilters(GlobalFilterCollection filters) { // filters.Add(new HandleErrorAttribute()); filters.Add(new ErrorLoggerAttribute()); }
你有没有想过扩展HandleError属性? 此外,斯科特在这里有一个关于控制器/操作过滤拦截器的好博客文章。
您可以尝试检查HttpContext.Error,但我不知道这一点。
Error.aspx视图是这样定义的:
namespace MvcApplication1.Views.Shared { public partial class Error : ViewPage<HandleErrorInfo> { } }
HandleErrorInfo有三个属性:stringActionNamestringControllerNameexceptionexception
您应该能够访问HandleErrorInfo,并因此在视图中的exception。
- 你在哪里存储asp.net mvc项目的图像,以及如何从site.master中引用它们
- 在使用System.DirectoryServices时尝试访问卸载的AppDomain
- 具有数据属性的SelectListItem
- Web API和ValidateAntiForgeryToken
- ASP.NET MVC的下拉列表中有一个默认的空选项
- 当优化设置为true时,MVC4 – Bundling不起作用
- Razor MVC使用Model Array填充Javascript数组
- Server 2012 IIS 8 MVC应用程序显示默认的IIS主页或403/404错误
- 使用Html.ActionLink在不同的控制器上调用操作