如何在基于ASP.NET Web API与OWIN的项目中集成ELMAH?
在ASP.NET Web API + OWIN项目中集成ELMAH的解决方案
你说得太对了——原生ELMAH是基于传统ASP.NET管道构建的,和OWIN的请求处理流程完全不兼容,直接装NuGet包肯定没用,/elmah.axd的请求根本到不了ELMAH那里。下面给你两种可靠的解决方式,从省心的现成方案到自定义适配都有:
方式一:使用官方适配的NuGet包(最推荐)
这是社区已经做好的成熟适配,上手最快:
安装必要依赖包:
- 先装ELMAH核心包:
Install-Package Elmah - 再装OWIN适配包:
Install-Package Elmah.OWIN - 如果你的项目托管在IIS上,务必确保安装了
Microsoft.Owin.Host.SystemWeb(绝大多数Web API项目都需要它来桥接OWIN和IIS管道)
- 先装ELMAH核心包:
配置OWIN启动类(Startup.cs):
重点注意中间件注册顺序——ELMAH的中间件必须放在Web API之前,这样它才能捕获到Web API处理过程中抛出的异常。代码示例:using Elmah; using Microsoft.Owin; using Owin; [assembly: OwinStartup(typeof(YourProjectNamespace.Startup))] namespace YourProjectNamespace { public class Startup { public void Configuration(IAppBuilder app) { // 先注册ELMAH OWIN中间件 app.UseElmah(); // 再配置Web API var config = new HttpConfiguration(); WebApiConfig.Register(config); app.UseWebApi(config); } } }给ELMAH加权限保护(可选但强烈建议):
别让未授权用户随便访问/elmah.axd,在Web.config里添加权限限制:<configuration> <location path="elmah.axd"> <system.web> <authorization> <allow roles="Admin"/> <!-- 仅允许管理员角色访问 --> <deny users="*"/> <!-- 拒绝其他所有用户 --> </authorization> </system.web> </location> </configuration>
方式二:手动编写OWIN中间件(适配特殊场景)
如果Elmah.OWIN包满足不了你的自定义需求,或者你找不到这个包,可以自己写个中间件桥接OWIN和ELMAH:
先确保已经安装了
Elmah核心NuGet包。创建自定义中间件类:
using Elmah; using Microsoft.Owin; using System; using System.Threading.Tasks; using System.Web; public class ElmahOwinMiddleware : OwinMiddleware { public ElmahOwinMiddleware(OwinMiddleware next) : base(next) { } public override async Task Invoke(IOwinContext context) { // 先让后续中间件(比如Web API)处理请求 await Next.Invoke(context); // 捕获请求中的异常,交给ELMAH记录 var exception = context.Get<Exception>("System.Web.Mvc.Exception"); if (exception != null) { ErrorSignal.FromCurrentContext().Raise(exception); } // 处理/elmah.axd的请求,直接交给ELMAH的处理程序 if (context.Request.Path.Value.Equals("/elmah.axd", StringComparison.OrdinalIgnoreCase)) { var httpContext = context.Get<HttpContextBase>(typeof(HttpContextBase).FullName); if (httpContext != null) { var handler = new Elmah.ErrorLogPageFactory(); handler.GetHandler(httpContext, "GET", "/elmah.axd", "/").ProcessRequest(httpContext); context.Response.StatusCode = 200; context.Response.ContentType = "text/html"; } } } }在Startup.cs里注册这个自定义中间件:
public void Configuration(IAppBuilder app) { // 注册自定义ELMAH中间件 app.Use<ElmahOwinMiddleware>(); // 配置Web API var config = new HttpConfiguration(); WebApiConfig.Register(config); app.UseWebApi(config); }
关键注意事项
- 中间件顺序绝对不能乱:ELMAH必须在Web API之前注册,否则无法捕获Web API抛出的异常。
- 如果是自托管(非IIS)的OWIN项目,要确保ELMAH的日志存储配置正确,比如在Web.config里设置
errorLog节点,或者用代码初始化日志提供者。 - 测试时可以故意抛出一个异常(比如在控制器里写
throw new Exception("测试ELMAH捕获")),然后访问/elmah.axd验证是否能看到这条异常记录。
内容的提问来源于stack exchange,提问作者Afshar
相关产品推荐
相关产品推荐

