簡體   English   中英

如何為IIS7集成自定義HttpModule

[英]How to integrate Custom HttpModule for IIS7

我在IIS 7.0 Web服務器上配置了asp.net Web應用程序。 我在將自定義HTTPModule集成到我的web.config中時遇到問題。 但是,該代碼適用於Web服務器中的Visual Studio構建。 有人可以看看我是否做錯了嗎?

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

如果有人可以幫助我解決這個問題,我將非常高興。 希望這篇文章可以在需要的時候幫助其他程序員。

問題出在應用程序池中。 我將“ ManagedPipelineMode”屬性從“ Integrated”更改為“ Classic”,從而解決了該問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM