簡體   English   中英

沒有調用HttpModule Init方法

[英]HttpModule Init method were not called

最近我正在實施一個HttpMoudle。 並且System.NullReferenceException: Object reference not set to an instance of an object.了錯誤,即System.NullReferenceException: Object reference not set to an instance of an object.

這是我的代碼。

public class MyHttpModuler : IHttpModule
    {
        private static IAuthProvider authProvider=null;
        #region IHttpModule members
        /// <summary>
        /// Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>.
        /// </summary>
        public void Dispose()
        {
            authProvider.Dispose();
            authProvider = null;
        }

        public void Init(HttpApplication application)
        {
            authProvider = new BasicAuthProvider("achievo");
            application.BeginRequest += new EventHandler(Application_BeginRequest);

        }

        private void Application_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication)sender;
            HttpRequest request = app.Request;
            HttpResponse response = app.Response;
            TryAuthenticate(app);                    
        }
        #endregion


        #region private method
        /// <summary>
        /// Tries to authenticate the user
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private bool TryAuthenticate(HttpApplication context)
        {
            string authHeader = context.Request.Headers["Authorization"];
            if (!string.IsNullOrEmpty(authHeader))
            {
                if (authHeader.StartsWith("basic ", StringComparison.InvariantCultureIgnoreCase))
                {

                    string userNameAndPassword = Encoding.Default.GetString(
                        Convert.FromBase64String(authHeader.Substring(6)));
                    string[] parts = userNameAndPassword.Split(':');
                     if (authProvider.IsValidUser(parts[0], parts[1]))
                    {
                        //the authProvider object sometimes is null .Why?                            
                        return true;
                    }
                }
            }
            return false;
        }
        #endregion
    }

public class BasicAuthProvider : IAuthProvider
    {

        #region IAuthProvider Members

        public string DomainName { get; set; }

        public BasicAuthProvider(string sDmName)
        {
            DomainName = sDmName;
        }

        public bool IsValidUser(string userName, string password)
        {

            string sFullName = "LDAP://" + DomainName + ".com";
            bool bLogin = ADHelper.IsAuthenticated(sFullName, DomainName + @"\" + userName, password);
            return bLogin;
        }


        public bool IsRequestAllowed(HttpRequest request,string sName)
        {
            return sName == "joe.wang";
        }



        public void Dispose()
        {

        }

        #endregion
    }

特別是當多個用戶進入網站時。 發生NullReferenceException的例外。 當我調試時,我發現有時可能不會調用Init方法。 也許這就是異常發生的原因。 有人可以幫我檢查一下嗎?謝謝

您已將主對象authProvider設置為靜態,因此您需要在進行同步時將其刪除並刪除它。

private static IAuthProvider authProvider=null;

所以你需要把它寫成:

public class MyHttpModuler : IHttpModule
    {
        //can not be shared with others request.
        //private IAuthProvider authProvider = null;

        //We do not need it now.
        //private static readonly object _lockObj = new object();

        #region IHttpModule members
        /// <summary>
        /// Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>.
        /// </summary>
        public void Dispose()
        {
            //authProvider.Dispose();
        //authProvider = null;
        }

        public void Init(HttpApplication application)
        { 

            application.BeginRequest += new EventHandler(Application_BeginRequest);       
        }

        private void Application_BeginRequest(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication)sender;
            HttpRequest request = app.Request;
            HttpResponse response = app.Response;
            TryAuthenticate(app);                    
        }
        #endregion


        #region private method
        /// <summary>
        /// Tries to authenticate the user
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns></returns>
        private bool TryAuthenticate(HttpApplication context)
        {
            IAuthProvider authProvider = new BasicAuthProvider("achievo");  
            string authHeader = context.Request.Headers["Authorization"];
            if (!string.IsNullOrEmpty(authHeader))
            {
                if (authHeader.StartsWith("basic ", StringComparison.InvariantCultureIgnoreCase))
                {

                    string userNameAndPassword = Encoding.Default.GetString(
                        Convert.FromBase64String(authHeader.Substring(6)));
                    string[] parts = userNameAndPassword.Split(':');
                     if (authProvider.IsValidUser(parts[0], parts[1]))
                    {
                        //the authProvider object sometimes is null .Why?     
                        authProvider=null;                        
                        return true;
                    }
                }
            }
            authProvider=null;  
            return false;
        }
        #endregion
    }

問題是(正如Aristos指出的那樣)你已經使authProvider靜態的。

這意味着當幾個用戶同時生成請求時,會有幾個HttpModule同時運行的實例。 但他們都將共享一個 authProvider

因此, 用戶A可能會啟動請求,導致您的模塊的新實例運行它的Init方法。 然后處理該請求的線程被置於保持狀態,並且來自用戶B的另一個請求啟動,導致另一個模塊的新intance運行它的Init方法。 這將覆蓋在用戶A的請求中放置的authProvider中的實例。 然后線程被置於保持狀態,並恢復用戶A的前一個線程並完成處理請求,從而處理authProvider (由用戶B的請求設置)並將其設置為null。 之后,用戶B的請求再次恢復,並發現authProvider現在為空。

根據您提供的代碼,似乎最簡單的解決方案是簡單地從行中刪除static關鍵字:

private static IAuthProvider authProvider=null;

然后, HttpModule每個實例都擁有它自己的authProvider副本,一個請求不會影響另一個請求的狀態。

暫無
暫無

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

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