2013-11-27 38 views
0

我在IIS 7.0 webserver上配置了asp.net web應用程序。我有問題將自定義HTTPModule集成到我的web.config中。該代碼適用於在Web服務器中構建Visual Studio。有人可以請看看並告訴我我可能會做錯什麼嗎?如何爲IIS7集成自定義HttpModule

using System; 
using System.Globalization; 
using System.IO; 
using System.Runtime.InteropServices; 
using System.Threading; 
using System.Web; 

namespace Realpage.HTTPModule.UnhandledException 
{ 
    using System.Configuration; 
    using System.Reflection; 

    using Elmah; 

    public class ElmahLogger : IHttpModule 
    { 
     static int unhandledExceptionCount; 

     static readonly object InitLock = new object(); 
     static bool initialized; 

     private static string elmahDirectory; 
     private static readonly FieldInfo elmahLogPathField = 
      typeof(XmlFileErrorLog).GetField("_logPath", BindingFlags.NonPublic | BindingFlags.Instance); 
     public void Init(HttpApplication httpApplication) 
     { 
      // Do this one time for each AppDomain. 
      if (initialized) 
      { 
       return; 
      } 
      lock (InitLock) 
      { 
       if (initialized) 
       { 
        return; 
       } 
       var webenginePath = Path.Combine(RuntimeEnvironment.GetRuntimeDirectory(), "webengine.dll"); 
       if (!File.Exists(webenginePath)) 
       { 
        throw new Exception(String.Format(CultureInfo.InvariantCulture, 
         "Failed to locate webengine.dll at '{0}'. This module requires .NET Framework 2.0.", webenginePath)); 
       } 

       AppDomain.CurrentDomain.UnhandledException += OnUnhandledException; 
       httpApplication.BeginRequest += Application_BeginRequest; 
       initialized = true; 
       elmahDirectory = ConfigurationManager.AppSettings["ElmahLogPath"]; 
      } 
     } 

     static void Application_BeginRequest(Object sender, EventArgs e) 
     { 
      var xmlFileErrorLog = (XmlFileErrorLog)ErrorLog.GetDefault(HttpContext.Current); 
      elmahLogPathField.SetValue(xmlFileErrorLog, elmahDirectory); 
     } 

     public void Dispose() 
     { 
     } 

     static void OnUnhandledException(object o, UnhandledExceptionEventArgs e) 
     { 
      // Let this occur one time for each AppDomain. 
      if (Interlocked.Exchange(ref unhandledExceptionCount, 1) != 0) 
      { 
       return; 
      } 

      var xmlFileErrorLog = (XmlFileErrorLog)ErrorLog.GetDefault(HttpContext.Current); 
      elmahLogPathField.SetValue(xmlFileErrorLog, elmahDirectory); 

      var exception = (Exception)e.ExceptionObject; 
      var baseException = exception.GetBaseException(); 

      var error = new Error(baseException); 
      xmlFileErrorLog.Log(error); 
     } 
    } 
} 

實施模塊應該不是件難事:

<configuration> 
<system.web> 
<httpModules> 
     <add name="Realpage.HTTPModule.UnhandledException" type="Realpage.HTTPModule.UnhandledException.ElmahLogger" /> 
      <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
      <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah"/> 
      <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah"/> 
      <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah"/> 
     </httpModules> 
</system.web> 

<system.webServer> 
     <modules runAllManagedModulesForAllRequests="true"> 
      <remove name="ScriptModule"/> 
     <add name="RealpageHTTPModuleUnhandledException" type="Realpage.HTTPModule.UnhandledException.ElmahLogger, Realpage.HTTPModule.UnhandledException" 
      preCondition="managedHandler"/><!--This is the handler causing the issue--> 
     <add name="ScriptModule" preCondition="managedHandler" 
      type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/> 
     <add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" preCondition="managedHandler"/> 
      <add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" preCondition="managedHandler"/> 
      <add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" preCondition="managedHandler"/> 
     </modules> 
    </system.webServer> 

</configuration> 

但我得到以下錯誤:

[NullReferenceException: Object reference not set to an instance of an object.] 
    System.Web.PipelineModuleStepContainer.GetEventCount(RequestNotification notification, Boolean isPostEvent) +30 
    System.Web.PipelineStepManager.ResumeSteps(Exception error) +332 
    System.Web.HttpApplication.BeginProcessRequestNotification(HttpContext context, AsyncCallback cb) +113 
    System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +616 

我會很高興,如果有人可以幫我解決這個問題。希望這篇文章能幫助其他程序員解決他們需要的一天。

回答

0

該問題與應用程序池有關。我將「ManagedPipelineMode」屬性從「集成」更改爲「經典」,並解決了問題。