自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

ASP.NET常被忽視的一些細(xì)節(jié)

開發(fā) 后端
其實(shí)這里是ASP.NET應(yīng)用程序中一個(gè)容易被忽略的經(jīng)節(jié)。后來想想,類似這樣的細(xì)節(jié)問題何止這一個(gè),我今天就把我能想到的容易被忽視的細(xì)節(jié)問題都寫出來,希望大家小心這些問題。

前段時(shí)間碰到一個(gè)問題:為什么在ASP.NET程序中定時(shí)器有時(shí)候會(huì)不工作? 

這個(gè)問題看起來很奇怪,代碼好像也沒錯(cuò),但就是結(jié)果與預(yù)期不一致。

其實(shí)這里是ASP.NET應(yīng)用程序中一個(gè)容易被忽略的經(jīng)節(jié)。后來想想,類似這樣的細(xì)節(jié)問題何止這一個(gè),我今天就把我能想到的容易被忽視的細(xì)節(jié)問題都寫出來,希望大家小心這些問題。 

想到我以前的博客中也零散的說過了一些,所以這篇博客中也把它們列出來了,不過,對(duì)于以前談過的內(nèi)容,這里將只會(huì)簡(jiǎn)略地說明。 

HttpContext.Current并非無處不在

這個(gè)問題是我上個(gè)月的博客中提到的問題,原文鏈接:http://www.cnblogs.com/fish-li/archive/2013/04/06/3002940.html

在以下情形中訪問HttpContext.Current將會(huì)返回null

1. 定時(shí)器的回調(diào)。

2. Cache的移除通知。

3. APM模式下異步完成回調(diào)。

4. 主動(dòng)創(chuàng)建線程或者將任務(wù)交給線程池來執(zhí)行。 

所以,在寫類庫時(shí),請(qǐng)注意這個(gè)問題。

Application_Start的異常與IIS經(jīng)典模式

在IIS6或者II7的經(jīng)典模式下運(yùn)行ASP.NET程序時(shí),如果Application_Start事件中拋出了未捕獲異常,那么 這個(gè)異常將顯示一次。

關(guān)于這個(gè)問題的更多細(xì)節(jié)介紹請(qǐng)點(diǎn)擊:http://www.cnblogs.com/fish-li/archive/2013/03/24/2979780.html

QueryString,Form允許重復(fù)的KEY

我們經(jīng)常見到的集合,例如:Hashtable, Dictionary,它們都要求KEY是唯一的,然而, HttpRequest的QueryString,Form集合實(shí)例卻 允許KEY重復(fù),當(dāng)遇到KEY重復(fù)時(shí),通過索引器訪問集合時(shí), 會(huì)將KEY對(duì)應(yīng)的所有元素值用逗號(hào)拼接起來。

為什么會(huì)這樣,因?yàn)檫@二個(gè)集合的類型是NameValueCollection,類似的,Headers集合也是這樣。 

由于這個(gè)特殊性與我們常見的情形不一致,所以我們需要注意這個(gè)差別,當(dāng)然了,有些時(shí)候我們還可以利用這個(gè)行為實(shí)現(xiàn)一些特殊的需求,關(guān)于這個(gè)細(xì)節(jié)的更多介紹請(qǐng)參考:http://www.cnblogs.com/fish-li/archive/2011/12/06/2278463.html ,在這篇博客中,還介紹了HttpRequest的二個(gè)索引器也是值得我們注意的。 

ashx的重用問題

很多ASP.NET的開發(fā)人員都應(yīng)該創(chuàng)建過ashx文件,例如下面這個(gè): 

 

  1. public class Handler1 : IHttpHandler {  
  2.     public bool IsReusable {  
  3.         get {  
  4.             return false;  
  5.         }  
  6.     }  

 

我想不少人會(huì)對(duì)IsReusable這個(gè)屬性感到好奇,于是去查一下IHttpHandler的定義,找到這個(gè)解釋, 

 

  1. // 摘要:  
  2. //     獲取一個(gè)值,該值指示其他請(qǐng)求是否可以使用 System.Web.IHttpHandler 實(shí)例。  
  3. //  
  4. // 返回結(jié)果:  
  5. //     如果 System.Web.IHttpHandler 實(shí)例可再次使用,則為 true;否則為 false。  
  6. bool IsReusable { get; } 

 

看到可以重用,有些對(duì)性能關(guān)注的人可能會(huì)將它修改為返回true,其實(shí)改成什么都一樣,因?yàn)樗黄鹱饔谩?/p>

不起作用的原因在這篇博客中有說明:http://www.cnblogs.com/fish-li/archive/2012/01/29/2331477.html

當(dāng)前登錄用戶信息有時(shí)獲取不到

在ASP.NET中,提供了以下方法讓我們獲取當(dāng)前用戶的信息,例如: 

 

  1. if( HttpContext.Current != null ) {  
  2.  
  3.     // 檢查當(dāng)前用戶是否已為一個(gè)已登錄用戶    bool isAuthenticated = HttpContext.Current.Request.IsAuthenticated;  
  4.  
  5.     // 獲取當(dāng)前請(qǐng)求的用戶名    string userName = HttpContext.Current.User.Identity.Name;  
  6. }  

 

不過,這段代碼放在不同的地方,效果卻截然不同。 

最近就遇到一個(gè)問題:有人問我為什么總是取不當(dāng)前用戶的用戶名。

網(wǎng)站采用的是Windows身份認(rèn)證,因此,所有的請(qǐng)求都是經(jīng)過IIS認(rèn)證過的,理論上說,變量isAuthenticated應(yīng)該返回true,而userName應(yīng)該是當(dāng)前請(qǐng)求的用戶名(Windows登錄名),然而呢,在調(diào)試時(shí), isAuthenticated的值是false, 后面的代碼直接拋出一個(gè)空引用異常,因?yàn)閁ser對(duì)象為null,太奇怪了,是嗎? 

當(dāng)出現(xiàn)這種情況時(shí),我們應(yīng)該檢查代碼在哪里被調(diào)用的。

結(jié)果在我的追問下,發(fā)現(xiàn)代碼是在一個(gè)HttpModule中調(diào)用的,且發(fā)生在訂閱HttpApplication的BeginRequest事件中。找到這里,原因也就找到了,此時(shí)(在這個(gè)階段)還沒有經(jīng)過ASP.NET的身份認(rèn)證檢查, User對(duì)象對(duì)象根本就沒有構(gòu)造出來,現(xiàn)在去訪問,當(dāng)然取不到結(jié)果。 

憑良心說,這個(gè)還真算不上ASP.NET留給我們的坑,只怪一些人對(duì)管線事件不了解。 

#p#

Timer可能會(huì)不起作用

有時(shí)候我們會(huì)遇到一些諸如執(zhí)行定時(shí)任務(wù)的需求,于是有些人可能會(huì)想到用定時(shí)器來實(shí)現(xiàn),在.net framework中,有二個(gè)Timer類型可以用于ASP.NET環(huán)境中,不過,Timer有可能會(huì)不起作用,具體表現(xiàn)情況也會(huì)讓你難以描述:不知道在什么時(shí)候定時(shí)器就停止工作了。 

這個(gè)問題很奇怪:當(dāng)你在調(diào)試模式下,定時(shí)器是一直能正常工作的,但當(dāng)你把網(wǎng)站部署起來,運(yùn)行時(shí)間久一些,便會(huì)發(fā)現(xiàn)定時(shí)器沒有正常工作。 

為什么會(huì)這樣呢?

答案是:當(dāng)網(wǎng)站在一段時(shí)間沒有請(qǐng)求后,進(jìn)程會(huì)被IIS回收(釋放)。

所以,在ASP.NET程序不適合執(zhí)行【長久性】的定時(shí)任務(wù),除非你能接受定時(shí)器會(huì)停止工作。

類似的問題還有:在ASP.NET程序中將某個(gè)方法做為回調(diào)方法傳給Win32程序,發(fā)現(xiàn)回調(diào)沒有響應(yīng)。 

正是由于這個(gè)原因,建議將長久性的定時(shí)任務(wù)或者接收Win32回調(diào)的程序用Windows Service的程序來實(shí)現(xiàn) 

Session與復(fù)雜數(shù)據(jù)類型

Session有三種工作模式,拿ASPX頁面來說,EnableSessionState指令有三個(gè)可選值:true, false, ReadOnly 

EnableSessionState="false",這個(gè)容易理解:不使用Session。 

EnableSessionState="ReadOnly",從字面上來說,就是Session是只讀的。

只讀的控件不允許用戶修改,然而Session的只讀模式是說:你可以改,但我不保存你的修改。這樣理解沒有問題吧。 

EnableSessionState="true",表示Session支持可讀可寫。

當(dāng)你更新了Session的內(nèi)容之后,當(dāng)前會(huì)話的所有Session數(shù)據(jù)將會(huì)被重新保存。 

進(jìn)程內(nèi)Session容易丟失,且不支持多臺(tái)Web服務(wù)器共享數(shù)據(jù),因此選擇這種保存方法的人不多,大多數(shù)人會(huì)選擇狀態(tài)服務(wù)或者SQL Server來保存,那么這里就有一個(gè)問題需要關(guān)注了:當(dāng)Session模式是EnableSessionState="true"時(shí),如果你訪問了一個(gè)復(fù)雜對(duì)象(不是系統(tǒng)值類型也不是字符串),不管你有沒有修改它,Session的保存操作都會(huì)執(zhí)行。對(duì)于進(jìn)程外Session,保存操作意味著需要執(zhí)行序列化,還可以會(huì)有網(wǎng)絡(luò)傳輸?shù)拈_銷,它們會(huì)影響性能。 

如果上面的描述不容易理解的話,請(qǐng)看下面的示例代碼: 

 

  1. string sessionValue = Session["s2"as string;  
  2. if( sessionValue == null ) {  
  3.     Session["s2"] = "Fish Li";  
  4.     sessionValue = Session["s2"as string;  
  5. }  

 

當(dāng)這個(gè)頁面***運(yùn)行時(shí),Session被修改了,因此會(huì)有保存的操作發(fā)生。但是后面的訪問就不會(huì)有保存的動(dòng)作。 

再看另一段代碼: 

 

  1. // TestData是一個(gè)自定義類型。TestData sessionValue = Session["s1"] as TestData;  
  2. if( sessionValue == null ) {  
  3.     Session["s1"] = new TestData { IntValue = 5, StrValue = "Fish Li" };  
  4.     sessionValue = Session["s1"as TestData;  
  5. }  

 

此時(shí)每次執(zhí)行這段代碼時(shí),都會(huì)有保存操作發(fā)生(只要是EnableSessionState="true")。 

我再重申一遍:這個(gè)問題只有當(dāng)EnableSessionState="true",且訪問復(fù)雜對(duì)象(不是系統(tǒng)值類型也不是字符串)才會(huì)發(fā)生。對(duì)于進(jìn)程內(nèi)Session來說,這個(gè)問題的影響不大,但是對(duì)于進(jìn)程外Session來說,會(huì)對(duì)性能產(chǎn)生一些影響,到底有多大的影響,要根據(jù)Session的數(shù)據(jù)量以及用戶的并發(fā)度來決定。 

列出這個(gè)問題只是想告訴大家:如果你確實(shí)需要使用Session,請(qǐng)盡量在Session中保存【不可變】的簡(jiǎn)單數(shù)據(jù),尤其是不要保持Session的默認(rèn)設(shè)置(EnableSessionState="true")。 

檢驗(yàn)這個(gè)問題的方法是:實(shí)現(xiàn)一個(gè)自定義的SessionStateStoreProviderBase派生類,然后調(diào)試觀察。 SessionStateItemCollection的二個(gè)索引器也會(huì)給你一個(gè)答案。 

DateTime的JSON序列化

在SP.NET3.5中,微軟為ASP.NET為設(shè)計(jì)了一個(gè)JSON序列化的工具類, System.Web.Script.Serialization.JavaScriptSerializer,這個(gè)類的使用很廣泛,而且比WCF的那個(gè)JSON序列化類的兼容性要好。不過,這個(gè)類有一個(gè)問題,在序列化DataTime類型時(shí),它生成的結(jié)果會(huì)讓所有人感覺別扭,其實(shí)序列化的結(jié)果表現(xiàn)形式還個(gè)小問題,在前端寫個(gè)轉(zhuǎn)換函數(shù)就能解決,然而,如果你需要 用序列化和反序列化的方法來做對(duì)象的持久化,就會(huì)遇到問題,例如下面的代碼: 

 

  1. DateTime dt1 = DateTime.Now;  
  2. JavaScriptSerializer jss = new JavaScriptSerializer();  
  3.  
  4. string json = jss.Serialize(dt1);  
  5. DateTime dt2 = jss.Deserialize<DateTime>(json);  
  6.  
  7. context.Response.Write(dt1 == dt2);  

 

瀏覽器顯示的結(jié)果會(huì)讓人感到很意外,竟然是:False 

出現(xiàn)這個(gè)原因與JavaScript的時(shí)間格式有關(guān),它使用了UTC時(shí)間,不過,這個(gè)理由讓人感到難以接受,畢竟其它的反序列化都能還原對(duì)象,例如二進(jìn)制序列化和XML都能正確的還原對(duì)象。沒辦法,這里只能算是個(gè)坑了,所以,如果你要做對(duì)象的持久化操作,盡量不要選擇JSON序列化。 

原文鏈接:http://www.cnblogs.com/fish-li/archive/2013/05/28/3104750.html

責(zé)任編輯:林師授 來源: 博客園
相關(guān)推薦

2012-07-03 13:55:00

ASP.NET

2009-09-04 13:11:25

ASP.NET生成XM

2011-04-29 09:35:43

打印紙打印機(jī)

2009-08-21 18:05:23

ASP.NET Ses

2009-12-11 14:17:36

ASP.NET Coo

2009-08-04 16:06:19

ASP.NET代碼分離

2013-06-07 08:48:37

Android開發(fā)注意事項(xiàng)

2009-08-14 17:49:02

ASP.NET MVC

2019-03-28 13:50:47

大數(shù)據(jù)面試Hadoop

2019-02-28 19:45:06

SQL錯(cuò)誤用法數(shù)據(jù)庫

2017-02-08 09:51:27

JavaScript細(xì)節(jié)

2009-07-31 18:00:35

ASP.NET工作流學(xué)

2018-10-18 09:20:27

云計(jì)算配置錯(cuò)誤

2009-08-03 18:16:46

ASP.NET Web

2022-04-27 22:07:32

SQL數(shù)據(jù)庫分頁查詢

2022-10-20 07:47:46

2018-12-19 08:51:35

Docker動(dòng)態(tài)工具

2015-05-20 11:06:54

2019-09-24 21:00:59

SQL數(shù)據(jù)庫基礎(chǔ)數(shù)據(jù)庫

2010-01-28 10:11:18

IT金飯碗
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)