ASP.NET線上使用者列表精確版——解決使用者意外退出線上列表無法及時更新問題
最近所做的一個專案需要用到的線上使用者列表,上網搜尋了一下發現現有的解決方案對使用者意外退出的處理均不是太理想。一般來說,使用者離開系統的方式有三種:主動登出、會話超時、直接關閉瀏覽器,對於前兩種,我們很容易便可將該使用者從線上列表中清除,關鍵是第三種(很多使用者都是直接關閉視窗的~~鬱悶ing),程式無法捕獲視窗關閉的精確時間,只能等到會話超時後在能將該使用者清除出在線列表,假設我們設定會話超時時間為60分鐘,而使用者登陸系統隨便瀏覽一個頁面就以關閉瀏覽器的方式退出的話,我們要在將近1小時後才能從線上列表中將該使用者清除出去(想象一下,系統顯示n多人線上,可能除了你之外其他的n-1人都關機走人了,汗一個先```),而本文將嘗試尋找一個解決方案把這種尷尬降至最低。
我的大概思路是,給每線上使用者增加一個RefreshTime屬性,建立一個負責將當前使用者的RefreshTime屬性設定為當前時間的單獨頁面(Refresh.aspx),然後在系統的主要頁面(也可以是所有頁面)中通過xmlhttp不斷地請求Refresh.aspx頁面,一旦使用者關閉了與本系統相關的所有視窗,即以直接關閉瀏覽器的方式退出系統,那麼該使用者的RefreshTime屬性便不會自動更新了,我們再設定一個自動重新整理的超時時間(這個要比會話超時短很多_refreshTimeout),當發現某使用者超過_refreshTimeout的時間沒有自動重新整理,就能判定該使用者已經以直接關閉瀏覽器的方式退出了。
假設我們設定會話超時時間為60分鐘,自動重新整理超時時間為1分鐘,在客戶端通過xmlhttp每隔25秒(之所以不設1分鐘,是防止網速慢的時候訪問Refresh.aspx超時,個人感覺,不一定正確)訪問一次Refresh.aspx頁面,在使用者登陸、使用者登出、檢測使用者是否線上的時候都執行清理超時使用者(包括會話超時和自動重新整理超時)操作,這樣一來,線上使用者列表的統計誤差就由60分鐘降至1分鐘了。
==========================================
具體實現如下:
1、 新建一個名為ActiveUser的類,儲存單個活動使用者資料。
/// <summary>
/// 單個線上使用者資料,無法繼承此類。
/// </summary>
public sealed class ActiveUser
{
private readonly string _ticket; //票據名稱
private readonly string _username; //登陸使用者名稱
private readonly string _truename; //登陸使用者名稱
private readonly string _roleid; //角色
private readonly DateTime _refreshtime; //最新重新整理時間
private readonly DateTime _activetime; //最新活動時間
private readonly string _clientip; //登陸IP
public ActiveUser(string Ticket,string UserName,string TrueName,string RoleID,string ClientIP) {
this._ticket=Ticket;
this._username=UserName;
this._truename=TrueName;
this._roleid=RoleID;
this._refreshtime=DateTime.Now;
this._activetime=DateTime.Now;
this._clientip=ClientIP;
}
public ActiveUser(string Ticket,string UserName,string TrueName,string RoleID,DateTime RefreshTime,DateTime ActiveTime,string ClientIP) {
this._ticket=Ticket;
this._username=UserName;
this._truename=TrueName;
this._roleid=RoleID;
this._refreshtime=RefreshTime;
this._activetime=ActiveTime;
this._clientip=ClientIP;
}
public string Ticket { get{return _ticket;} }
public string UserName { get{return _username;} }
public string TrueName { get{return _truename;} }
public string RoleID { get{return _roleid;} }
public DateTime RefreshTime { get{return _refreshtime;} }
public DateTime ActiveTime { get{return _activetime;} }
public string ClientIP { get{return _clientip;} }
}
2、 新建一個名為PassPort的類,儲存線上使用者列表。
/// <summary>
/// PassPort 儲存線上使用者列表。
/// </summary>
public class PassPort
{
private static DataTable _activeusers;
private int _activeTimeout;
private int _refreshTimeout;
/// <summary>
/// 初始化線上使用者表。
/// </summary>
private void userstableFormat()
{
if(_activeusers==null) {
_activeusers = new DataTable("ActiveUsers");
DataColumn myDataColumn;
System.Type mystringtype;
mystringtype = System.Type.GetType("System.String");
System.Type mytimetype;
mytimetype = System.Type.GetType("System.DateTime");
myDataColumn = new DataColumn("Ticket",mystringtype);
_activeusers.Columns.Add(myDataColumn);
myDataColumn = new DataColumn("UserName",mystringtype);
_activeusers.Columns.Add(myDataColumn);
myDataColumn = new DataColumn("TrueName",mystringtype);
_activeusers.Columns.Add(myDataColumn);
myDataColumn = new DataColumn("RoleID",mystringtype);
_activeusers.Columns.Add(myDataColumn);
myDataColumn = new DataColumn("RefreshTime",mytimetype);
_activeusers.Columns.Add(myDataColumn);
myDataColumn = new DataColumn("ActiveTime",mytimetype);
_activeusers.Columns.Add(myDataColumn);
myDataColumn = new DataColumn("ClientIP",mystringtype);
_activeusers.Columns.Add(myDataColumn);
}
}
public PassPort()
{
userstableFormat(); //初始化線上使用者表
//活動超時時間初始化 單位:分鐘
try { _activeTimeout=int.Parse(ConfigurationSettings.AppSettings["ActiveTimeout"]); }
catch{ _activeTimeout=60; }
//自動重新整理超時時間初始化 單位:分鐘
try { _refreshTimeout=int.Parse(ConfigurationSettings.AppSettings["RefreshTimeout"]); }
catch{ _refreshTimeout=1; }
}
//全部使用者列表
public DataTable ActiveUsers
{
get{return _activeusers.Copy();}
}
/// <summary>
/// 新使用者登陸。
/// </summary>
public void Login(ActiveUser user,bool SingleLogin)
{
DelTimeOut(); //清除超時使用者
if(SingleLogin){
//若是單人登陸則登出原來登陸的使用者
this.Logout(user.UserName,false);
}
DataRow myRow;
try
{
myRow = _activeusers.NewRow();
myRow["Ticket"] = user.Ticket.Trim();
myRow["UserName"] = user.UserName.Trim();
myRow["TrueName"] = ""+user.TrueName.Trim();
myRow["RoleID"] = ""+user.RoleID.Trim();
myRow["ActiveTime"] = DateTime.Now;
myRow["RefreshTime"] = DateTime.Now;
myRow["ClientIP"] = user.ClientIP.Trim();
_activeusers.Rows.Add(myRow);
}
catch(Exception e)
{
throw(new Exception(e.Message));
}
_activeusers.AcceptChanges();
}
/// <summary>
///使用者登出,根據Ticket或UserName。
/// </summary>
private void Logout(string strUserKey,bool byTicket)
{
DelTimeOut(); //清除超時使用者
strUserKey=strUserKey.Trim();
string strExpr;
strExpr =byTicket ? "Ticket='" + strUserKey +"'" : "UserName='" + strUserKey + "'";
DataRow[] curUser;
curUser = _activeusers.Select(strExpr);
if (curUser.Length >0 )
{
for(int i = 0; i < curUser.Length; i ++)
{
curUser[i].Delete();
}
}
_activeusers.AcceptChanges();
}
/// <summary>
///使用者登出,根據Ticket。
/// </summary>
/// <param name="strTicket">要登出的使用者Ticket</param>
public void Logout(string strTicket){
this.Logout(strTicket,true);
}
/// <summary>
///清除超時使用者。
/// </summary>
private bool DelTimeOut()
{
string strExpr;
strExpr = "ActiveTime < '" + DateTime.Now.AddMinutes( 0 - _activeTimeout) + "'or RefreshTime < '"+DateTime.Now.AddMinutes( 0 - _refreshTimeout)+"'";
DataRow[] curUser;
curUser = _activeusers.Select(strExpr);
if (curUser.Length >0 )
{
for(int i = 0; i < curUser.Length; i ++)
{
curUser[i].Delete();
}
}
_activeusers.AcceptChanges();
return true;
}
/// <summary>
///更新使用者活動時間。
/// </summary>
public void ActiveTime(string strTicket)
{
DelTimeOut();
string strExpr;
strExpr = "Ticket='" + strTicket + "'";
DataRow[] curUser;
curUser = _activeusers.Select(strExpr);
if (curUser.Length >0 )
{
for(int i = 0; i < curUser.Length; i ++)
{
curUser[i]["ActiveTime"]=DateTime.Now;
curUser[i]["RefreshTime"]=DateTime.Now;
}
}
_activeusers.AcceptChanges();
}
/// <summary>
///更新系統自動重新整理時間。
/// </summary>
public void RefreshTime(string strTicket)
{
DelTimeOut();
string strExpr;
strExpr = "Ticket='" + strTicket + "'";
DataRow[] curUser;
curUser = _activeusers.Select(strExpr);
if (curUser.Length >0 )
{
for(int i = 0; i < curUser.Length; i ++)
{
curUser[i]["RefreshTime"]=DateTime.Now;
}
}
_activeusers.AcceptChanges();
}
private ActiveUser SingleUser(string strUserKey,bool byTicket)
{
strUserKey=strUserKey.Trim();
string strExpr;
ActiveUser myuser;
strExpr =byTicket ? "Ticket='" + strUserKey +"'" : "UserName='" + strUserKey + "'";
DataRow[] curUser;
curUser = _activeusers.Select(strExpr);
if (curUser.Length >0 )
{
string myTicket=(string)curUser[0]["Ticket"];
string myUser=(string)curUser[0]["UserName"];
string myName=(string)curUser[0]["TrueName"];
string myRoleID=(string)curUser[0]["RoleID"];
DateTime myActiveTime=(DateTime)curUser[0]["ActiveTime"];
DateTime myRefreshtime=(DateTime)curUser[0]["RefreshTime"];
string myClientIP =(string)curUser[0]["ClientIP"];
myuser=new ActiveUser(myTicket,myUser,myName,myRoleID,myActiveTime,myRefreshtime,myClientIP);
}
else
{
myuser=new ActiveUser("","","","","");
}
return myuser;
}
/// <summary>
///按Ticket獲取活動使用者。
/// </summary>
public ActiveUser SingleUser_byTicket(string strTicket)
{
return this.SingleUser(strTicket,true);
}
/// <summary>
///按UserName獲取活動使用者。
/// </summary>
public ActiveUser SingleUser_byUserName(string strUserName)
{
return this.SingleUser(strUserName,false);
}
/// <summary>
///按Ticket判斷使用者是否線上。
/// </summary>
public bool IsOnline_byTicket(string strTicket)
{
return (bool)(this.SingleUser(strTicket,true).UserName!="");
}
/// <summary>
///按UserName判斷使用者是否線上。
/// </summary>
public bool IsOnline_byUserName(string strUserName)
{
return (bool)(this.SingleUser(strUserName,false).UserName!="");
}
}
3、 新建一個繼承自PlaceHolder名為Refresh的類,執行更新自動重新整理時間操作。
/// <summary>
/// Refresh 執行更新自動重新整理時間操作。
/// </summary>
public class Refresh: PlaceHolder
{
/// <summary>
/// 設定儲存Ticket的Session名稱,預設為Ticket。
/// </summary>
public virtual string SessionName
{
get{
object obj1 = this.ViewState["SessionName"];
if (obj1 != null){ return ((string) obj1).Trim(); }
return "Ticket";
}
set{
this.ViewState["SessionName"] = value;
}
}
protected override void Render(HtmlTextWriter writer)
{
string myTicket=(string)this.Page.Session[this.SessionName];
if(myTicket!=null)
{
PassPort myPass = new PassPort();
myPass.RefreshTime(myTicket);
writer.Write("OK:"+DateTime.Now.ToString());
}
else{
writer.Write("Sorry:"+DateTime.Now.ToString());
}
base.Render(writer);
}
}
4、 新建一個繼承自PlaceHolder名為Script的類,生成執行xmlhttp的js指令碼。。
/// <summary>
/// Script 生成執行xmlhttp的js指令碼。
/// </summary>
public class Script: PlaceHolder
{
/// <summary>
/// 設定js自動重新整理的間隔時間,預設為25秒。
/// </summary>
public virtual int RefreshTime
{
get
{
object obj1 = this.ViewState["RefreshTime"];
if (obj1 != null){return int.Parse(((string) obj1).Trim());}
return 25;
}
set
{
this.ViewState["RefreshTime"] = value;
}
}
protected override void Render(HtmlTextWriter writer)
{
//從web.config中讀取xmlhttp的訪問地址
string refreshUrl=(string)ConfigurationSettings.AppSettings["refreshUrl"];
string scriptString = @" <script language=""JavaScript"">"+writer.NewLine;
scriptString += @" window.attachEvent(""onload"", "[email protected]"_postRefresh);"+writer.NewLine;
scriptString += @" var "[email protected]"_xmlhttp=null;"+writer.NewLine;
scriptString += @" function "[email protected]"_postRefresh(){"+writer.NewLine;
scriptString += @" var "[email protected]"_xmlhttp = new ActiveXObject(""Msxml2.XMLHTTP"");"+writer.NewLine;
scriptString += @" "[email protected]"_xmlhttp.Open(""POST"", """[email protected]""", false);"+writer.NewLine;
scriptString += @" "[email protected]"_xmlhttp.Send();"+writer.NewLine;
scriptString += @" var refreshStr= "[email protected]"_xmlhttp.responseText;"+writer.NewLine;
scriptString += @" try {"+writer.NewLine;
scriptString += @" var refreshStr2=refreshStr;"+writer.NewLine;
//scriptString += @" alert(refreshStr2);"+writer.NewLine;
scriptString += @" }"+writer.NewLine;
scriptString += @" catch(e) {}"+writer.NewLine;
scriptString += @" setTimeout("""[email protected]"_postRefresh()"","+this.RefreshTime.ToString()[email protected]"000);"+writer.NewLine;
scriptString += @" }"+writer.NewLine;
scriptString += @"<";
scriptString += @"/";
scriptString += @"script>"+writer.NewLine;
writer.Write(writer.NewLine);
writer.Write(scriptString);
writer.Write(writer.NewLine);
base.Render(writer);
}
}
注意以上四個類同屬於一個名為OnlineUser的工程,他們的名稱空間為OnlineUser,編譯生成一個dll。
===============================================
下面我簡單介紹一下呼叫方法:
1、 新建一個名為OnlineUserDemo的asp.net web應用程式
2、 在vs的工具箱選項卡上右擊,選擇[新增/移除項],瀏覽定位到OnlineUser.dll,確定即可把Refresh 和Script新增到工具箱。
3、 把自動生成的WebForm1.aspx刪除,並設定web.config
<appSettings>
<add key="ActiveTimeout" value="30" />
<add key="RefreshTimeout" value="1" />
<add key="refreshUrl" value="refresh.aspx" />
</appSettings>
4、 新增一個名為Online.aspx的web窗體,給該窗體新增一個Script控制元件,一個DataGrid控制元件(id為DataGrid1),兩個HyperLink控制元件(分別連結到login.aspx和logout.aspx,text屬性分別設定為“登陸”和“登出”),調整好四個控制元件的位置,轉到codebehind,在Page_Load中加入如下程式碼:
string myTicket=(string)this.Page.Session["Ticket"];
if(myTicket!=null)
{
OnlineUser.PassPort myPassPort= new OnlineUser.PassPort();
if(myPassPort.IsOnline_byTicket(this.Session["Ticket"].ToString()))
{
myPassPort.ActiveTime(this.Session["Ticket"].ToString());
DataGrid1.DataSource=myPassPort.ActiveUsers;
DataGrid1.DataBind();
}
else{
//若線上使用者列表中找不到當前使用者,則定向到登出頁面
Response.Redirect("Logout.aspx");
}
}
else{
Response.Redirect("Login.aspx");
}
5、 新增一個名為login.aspx的web窗體,給該窗體新增一個label控制元件(id為Label1),設定text屬性為“輸入一個使用者名稱”,再新增一個textbox控制元件(id為TextBox1)和一個button控制元件(id為Button1),調整好他們的位置,雙擊Button1控制元件轉到codebehind,為Button1的Click事件加入如下程式碼:
if(TextBox1.Text.Trim()=="")
{
//不能為空
String scriptString = @"<script language=JavaScript>";
scriptString += @"alert(""輸入一個使用者名稱/n"");";
scriptString += @"history.go(-1);";
scriptString += @"<";
scriptString += @"/";
scriptString += @"script>";
if(!this.Page.IsStartupScriptRegistered("Startup"))
this.Page.RegisterStartupScript("Startup", scriptString);
}
else{
OnlineUser.PassPort myPassPort= new OnlineUser.PassPort();
string myTicket=DateTime.Now.ToString("yyyyMMddHHmmss");
string myUser=TextBox1.Text.Trim();
string myClintIP=this.Request.UserHostAddress;
this.Session["Ticket"]=myTicket;
OnlineUser.ActiveUser myActiveUser=new OnlineUser.ActiveUser(myTicket,myUser,myUser,"test",myClintIP);
myPassPort.Login(myActiveUser,true);
Response.Redirect("Online.aspx");
}
6、 新增一個名為logout.aspx的web窗體,給該窗體新增一個HyperLink控制元件,指向login.aspx,text屬性設定為“重登陸”轉到codebehind,在Page_Load中加入如下程式碼:
OnlineUser.PassPort myPassPort= new OnlineUser.PassPort();
myPassPort.Logout(this.Session["Ticket"].ToString());
this.Session["Ticket"]="";
7、 新增一個名為Refresh.txt的文字檔案,設定其內容為:
<%@ Register TagPrefix="cc2" Namespace="OnlineUser" Assembly="OnlineUser" %>
<%@ Page %>
<cc2:Refresh id="myRefresh" runat="server"></cc2:Refresh>
把Refresh.txt改名為Refresh.aspx
8、 編譯生成工程。
===============================================
下面進行功能測試:
1、 開啟瀏覽器,在位址列輸入
http://你機器的IP地址/onlineuserdemo/Login.aspx
2、 輸入一個使用者名稱(假設是test1)登陸,自動轉到online.aspx頁面
3、 找同網段的另外一臺機器(設你的機器為a,這臺機器為b),重複執行第一步。
4、 輸入一個使用者名稱(假設是test2)登陸,自動轉到online.aspx頁面
5、 在b機器不斷重新整理online.aspx,若發現test1使用者RefreshTime每過25秒自動更新一次而ActiveTime不變(這個時候a機器不要重新整理頁面啊),則證明a機器的自動重新整理生效。
6、 在a機器不斷重新整理online.aspx,若發現test2使用者RefreshTime每過25秒自動更新一次而ActiveTime不變(這個時候b機器不要重新整理頁面啊),則證明b機器的自動重新整理生效。
7、 直接關閉一臺機器(假設是a)上的online.aspx瀏覽視窗,在另一臺機器(就是b啦)上重新整理online.aspx,若發現1分鐘後test1掉線線上使用者只剩下test2,證明通過_refreshTimeout清除線上使用者成功。
8、 若5、6、7三步正常,則大功告成,否則就再除錯除錯~~
==========================================================
這個看了後覺得很好,非常適合我用,唯一覺得不滿意的是客戶必須登入,實際應用中網站有很多訪客,也應該算是線上使用者,我對這個做了一點點修改,就可以用了,和大家共享。
1、在PassPort類增加:
/// <summary>
/// 使用者變更登入名。
/// </summary>
public void Login(string strTicket,string UserName,string TrueName)
{
DelTimeOut();
string strExpr;
strExpr = "Ticket='" + strTicket + "'";
DataRow[] curUser;
curUser = _activeusers.Select(strExpr);
if (curUser.Length >0 )
{
for(int i = 0; i < curUser.Length; i ++)
{
curUser[i]["ActiveTime"]=DateTime.Now;
curUser[i]["RefreshTime"]=DateTime.Now;
curUser[i]["UserName"] =UserName.Trim();
curUser[i]["TrueName"] =TrueName.Trim();
}
}
_activeusers.AcceptChanges();
}
2、把OnlineUserDemo的asp.net web應用程式的Global.axax.cs裡的Session_Start、Session_End改為:
protected void Session_Start(Object sender, EventArgs e)
{
OnlineUser.PassPort myPassPort= new onlineUser.PassPort();
string myTicket=DateTime.Now.ToString("yyyyMMddHHmmss");
string myUser="訪客";
string myClintIP=Request.UserHostAddress;
Session["Ticket"]=myTicket;
OnlineUser.ActiveUser myActiveUser=new OnlineUser.ActiveUser(myTicket,myUser,myUser,"test",myClintIP);
myPassPort.Login(myActiveUser,false);
}
附:網上現有的一些線上人數統計的文章
相關推薦
ASP.NET線上使用者列表精確版——解決使用者意外退出線上列表無法及時更新問題
最近所做的一個專案需要用到的線上使用者列表,上網搜尋了一下發現現有的解決方案對使用者意外退出的處理均不是太理想。一般來說,使用者離開系統的方式有三種:主動登出、會話超時、直接關閉瀏覽器,對於前兩種,我們很容易便可將該使用者從線上列表中清除,關鍵是第三種(很多使用者都
asp.net MVC 常見安全問題及解決方案
container coo baidu his ring article 調試工具 並且 part asp.net MVC 常見安全問題及解決方案一.CSRF (Cross-site request forgery跨站請求偽造,也被稱為“one click attack”或
asp.net Global.asax 不運行解決
ima png net 解決方法 publish 解決 alt sax img asp.net application的站點發布後 Global.asax 未運行,搞了好久終於解決, 解決方法如下: publish設置 該設置經測試在win server
C# 無法向會話狀態伺服器發出會話狀態請求。請確保 ASP.NET State Service (ASP.NET 狀態服務)已啟動"問題解決方法
異常詳細資訊: System.Web.HttpException: 無法向會話狀態伺服器發出會話狀態請求。請確保已啟動 ASP.NET State service,並且客戶端和伺服器埠是相同的。如果伺服器位於遠端計算機上,請檢查 HKEY_LOCAL_MACHINE\SYST
asp.net 呼叫帶證書的webservice解決辦法
最近在朋友弄一個調整省政府政務工作流的程式。。 需要把當前的資訊推送到政務網上,採用的是帶證書的https webservice。。 下面說一下實現過程 第一步,引用webservice地址,刪除web.config中相關配置。同時安裝好證書 用如下資料替換:
ASP.NET Ajax 跨域問題最佳解決方案
通過設定Access-Control-Allow-Origin來實現跨域。 例如:客戶端的域名是client.runoob.com,而請求的域名是server.runoob.com。 如果直接使用ajax訪問,會有以下錯誤: XMLHttpRequest cannot
dreamweaver中asp.net不能新增資料庫的解決方法
如果您在 Dreamweaver CS4、CS5 中新增一個網站,設定它的測試環境為 ASP.net 或 JSP 時,您會發現開始編輯時,不僅無法新增伺服器的資料庫連結,甚至也沒有任何伺服器行為?無論您如何檢查環境或是修改設定,就是找不到這些原有的資源。 難道Dreamweaver CS4、CS5 已經
中文VS2008中安裝ASP.NET MVC框架出現問題的解決方法
執行檔案AspNetMVCPreview2-setup.msi進行安裝,安裝完成後,發現在VS2008裡面並沒有MVC模板和相應的測試模版的出現。如果你用的是Microsoft Visual Studio 2008中文版,那以上問題就會發生。主要原因是ASP.NET MVC是英文的,所有都放
asp.net webservice 不能遠端除錯 解決方法
webservice介面是通過url地址進行呼叫的,在本地開發呼叫可以填寫資料值進行呼叫,可是佈署在伺服器後就不能遠端除錯沒有輸入引數的文字框,奇怪。後來,才知道在config配置一下就行了。<system.web> <webServices&
IE10 下 ASP.NET PageRequestManager、_doPostBack 未定義 解決方法
這包括FF5 關於 ASP.NET 4 和 ASP.NET 2.0 的 IE10 和 IE10 瀏覽器檔案。 您可以更新您的整個機器的瀏覽器檔案。 1.將檔案從複製。 \machines資料夾複製到\Windows\Microsoft.NET\Framework\v
asp.net 2安裝遇到問題的解決(由於無法建立應用程式域,因此未能執行請求。錯誤: 0x80070005 拒絕訪問)
1:安裝2.0之後,在IIS的虛擬目錄的屬性設定中會多出一個ASP.NET標籤,在那裡邊把執行時調整為2.0,預設使用的是1.1的執行時。 2: 這個是許可權問題, 首先檢查應用程式池的屬性,看看它是以什麼使用者身份執行的,一般是NETWORK SERVICE
asp.net基礎-xss發貼漏洞解決方案
解決方案:在顯示頁面的伺服器端程式改為 protected void Page_Load(object sender, EventArgs e) { //Response.Write(File.ReadAllText("c:/5.txt")); string s = F
ASP.NET第一次訪問慢的解決方法(MVC,Web Api)
問題現象 訪問asp.net web專案的時候,第一次訪問比較慢,當閒置一段時間後,再次訪問還是會非常慢。 問題原因 這是IIS回收造成的,再次訪問的時候會初始化操作,初始化需要耗費時間,所以訪問會比較慢,第二次訪問的時候不需要初始化操作,因此變快了。 解決辦法 IIS應用初始化會在網站第一次建立後
關於:“無法序列化會話狀態。在“StateServer”或“SQLServer”模式下,ASP.NET 將序列化會話狀態物件,因此不允許使用無法序列化的物件或 MarshalByRef 物件。如果自定義會話狀態儲存在“Custom”模式下執行了類似的序列化
錯誤描述: 無法序列化會話狀態。在“StateServer”或“SQLServer”模式下,ASP.NET 將序列化會話狀態物件,因此不允許使用無法序列化的物件或 MarshalByRef 物件。如果
ASP.NET多線程下使用HttpContext.Current為null解決方案
sdn lower null com 獲取文件 .html 模擬 public 一個 問題一:多線程下獲取文件絕對路徑 問題一:多線程下獲取文件絕對路徑 當我們使用HttpContext.Current.Server.MapPath(strPath)獲取絕對路徑時H
關於asp.net自動生成樹形下拉列表(資料庫版)
在 網上找了很久沒找到樹沒找到樹形下拉列表,於是自已寫了一個,(平時工作忙,沒時間,這段時間輕鬆點)給大家分享分享,有什麼不足之處還需廣大程式設計師同志們提一提 功能:無限級樹形下拉列表,通過資料庫繫結 表結構:最少也要兩個欄位 [ ID , FATHER_ID ] (var
ASP.NET Zero--解決方案結構(層)
ges 檢測 lan auto git png 其他 nan repos 解決方案結構(層) 創建和下載項目後,您將具有如下所示的解決方案結構: 解決方案有8個項目: Core項目包含域層類(如 實體 和 域服務)。 Application項目包含應用
Asp.net Web Api 解決跨域問題
asp oss ros ner div exec space out color using System; using System.Collections.Generic; using System.Linq; using System.Web; using Syst
ASP.NET中的母版頁
建議 cli 路徑 pla 自動 webapp 一個 服務 如果 添加一個"母版頁",使用<asp:ContentPlaceHolder>挖坑,新建的母版頁已經自動設置了兩個ContentPlaceHolder創建使用母版頁的具體頁面,WebSite是新建"We
ASP.NET 使用ajaxupload.js插件出現上傳較大文件失敗的解決方法
linu inf asp ctu idc code oca ace 去百度 在網上下載了一個ajaxupload.js插件,用於無刷新上傳圖片使的,然後就按照demo的例子去運行了一下,上傳啊什麽的都OK,但是正好上傳的示例圖片有一個比較大的,4M,5M的樣子,然後上傳就會