利用IHttpModule及Session_End事件进行在线会员统计遇到的问题

先放代码:

CountOnLineModule.cs

namespace YaLong.MIS.BIWebSite.HttpModule
{
public class CountOnLineModule : IHttpModule
{
public void Dispose()
{
}
public log4net.ILog smtplogger;
public void Init(HttpApplication application)
{
smtplogger = log4net.LogManager.GetLogger("logger.smtp");
application.AcquireRequestState += (new EventHandler(this.Application_AcquireRequestState));
}

private void Application_AcquireRequestState(Object source, EventArgs e)
{
string sessionID = string.Empty, userName = string.Empty, curLoadpage = string.Empty, userIP = string.Empty, userAgent = string.Empty;
HttpApplication mApplication = (HttpApplication)source;
HttpResponse Response = mApplication.Context.Response;
DataTable dt = null;
HttpBrowserCapabilities bc = null;
string OSName = string.Empty;
if (mApplication.Context.Application["OnlineUsers"] != null)
{
dt = (DataTable)mApplication.Context.Application["OnlineUsers"];
}
else
{
dt = new DataTable();//建表
dt.Columns.Add("SessionID");
dt.Columns.Add("UserIP");
dt.Columns.Add("UserName");
dt.Columns.Add("FirstLoadTime");
dt.Columns.Add("LastLoadTime");
dt.Columns.Add("Browser");
dt.Columns.Add("OSName");
dt.Columns.Add("UserAgent");
dt.Columns.Add("CurLoadpage");
}
//将当前用户添加到在线用户列表
if (mApplication.Context.Session != null)
{
if (mApplication.Context.Session.SessionID != null)
{
sessionID = mApplication.Context.Session.SessionID;
userName = PCurrent.User.UserName ?? "游客";
curLoadpage = mApplication.Context.Request.RawUrl ?? "地址未知";
DataRow[] rows = dt.Select("sessionID='" + sessionID + "'");
if (rows.Length > 0)//数据更新
{
if (rows[0].RowState != System.Data.DataRowState.Deleted)
{
rows[0]["LastLoadTime"] = System.DateTime.Now.ToString();//更新最后在线时间 实际没用
rows[0]["UserName"] = userName;
rows[0]["CurLoadpage"] = curLoadpage;
}
}
else
{
userIP = mApplication.Context.Request.UserHostAddress;
userAgent = mApplication.Context.Request.UserAgent;
bc = mApplication.Context.Request.Browser;
OSName = GetOSNameByUserAgent(mApplication.Context.Request);// "Win2000";
string Browser = bc.Browser + bc.Version;// bc.Type;
DateTime LoadTime = System.DateTime.Now;
try
{


dt.Rows.Add(new object[] { sessionID, userIP, userName, LoadTime.ToString(), LoadTime.ToString(), Browser, OSName, userAgent, curLoadpage });
}
catch (Exception ex)
{
string curStatus = "sessionID:" + sessionID + "userName:" + userName + "userAgent:" + userAgent + "在访问:" + curLoadpage;
smtplogger.Warn("添加在线访客信息失败:" + curStatus, ex);
}
}
}
dt.AcceptChanges();
mApplication.Context.Application["OnlineUsers"] = dt;

}
}

private string GetOSNameByUserAgent(HttpRequest httpRequest)
{
string userAgent = httpRequest.ServerVariables["HTTP_USER_AGENT"];
string osVersion = httpRequest.Browser.Platform;// "未知";
if (userAgent.Contains("NT 6.0"))
{
osVersion = "Windows Vista/Server 2008";
}
else if (userAgent.Contains("NT 5.2"))
{
osVersion = "Windows Server 2003";
}
else if (userAgent.Contains("NT 5.1"))
{
osVersion = "Windows XP";
}
else if (userAgent.Contains("NT 5"))
{
osVersion = "Windows 2000";
}
else if (userAgent.Contains("NT 4"))
{
osVersion = "Windows NT4";
}
else if (userAgent.Contains("Me"))
{
osVersion = "Windows Me";
}
else if (userAgent.Contains("98"))
{
osVersion = "Windows 98";
}
else if (userAgent.Contains("95"))
{
osVersion = "Windows 95";
}
else if (userAgent.Contains("Mac"))
{
osVersion = "Mac";
}
else if (userAgent.Contains("Unix"))
{
osVersion = "UNIX";
}
else if (userAgent.Contains("Linux"))
{
osVersion = "Linux";
}
else if (userAgent.Contains("SunOS"))
{
osVersion = "SunOS";
}
return osVersion;
}


}
}

Global.asax  session_end代码

    void Session_End(object sender, EventArgs e)
{
#region 删除过期会话 用户
string sessionID = Session.SessionID;
if (sessionID == null)
return;
System.Data.DataTable userTable = (System.Data.DataTable)Application["OnlineUsers"];
if (userTable == null)
return;
int rowCount = userTable.Rows.Count;
if (rowCount>1)
{
for (int i = 0; i < rowCount; i++)
{
if (userTable.Rows[i]["SessionID"].ToString() == sessionID)
{
if (userTable.Rows[i].RowState != System.Data.DataRowState.Deleted)
{
userTable.Rows.Remove(userTable.Rows[i]);
}
}
}
}

try
{
Application.Lock();
userTable.AcceptChanges();
Application["OnlineUsers"] = userTable;
Application.UnLock();
smtplogger.Warn("成功删除过期session:" + sessionID);
}
catch (Exception ex)
{
smtplogger.Warn("删除过期session出错:" + sessionID, ex);
}
#endregion
}

出现的问题:

在运行一段时间以后,发现有大量蜘蛛来网站访问,日志记录

添加在线访客信息失败:sessionID:ej22mwmfmj0k2i55g2i1o1jquserName:游客userAgent:

System.NullReferenceException: 未将对象引用设置到对象的实例。

上面的原因可能是userAgent为空值

添加在线访客信息失败:sessionID:userName:userAgent:在访问:

System.NullReferenceException: 未将对象引用设置到对象的实例。

上面的原因可能是sessionID:userName:userAgent均为空值

这里不解的是蜘蛛在访问时sessionID:userName:userAgent这些怎么会是空值呢?

难道部分蜘蛛的访问不会再服务器端产生sessionid或者userAgent吗

System.NullReferenceException: 未将对象引用设置到对象的实例。 在 ASP.global_asax.Session_End(Object sender, EventArgs e)

这里为何会出错?

另外,请各位大牛看看这种统计在线会员的方法在代码上还有什么问题?

附上一张蜘蛛访问截图

原文地址:https://www.cnblogs.com/hnsongbiao/p/2418935.html