![](/img/trans.png)
[英]Advanced: How many times does HttpModule Init() method get called during application's life?
[英]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.