日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

让UpdatePanel支持文件上传(4):数据传输与解析机制

發布時間:2025/3/8 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 让UpdatePanel支持文件上传(4):数据传输与解析机制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

現在就要開始整個項目中最有技巧的部分了。如果我們的組件需要在多種瀏覽器中正常的運行,我們必須好好考慮一下發送和解析數據的方式。如果我們把這部分的機制完全交給ASP.NET AJAX原有的行為來執行,則會遇到問題。下面的代碼片斷就是IE 7和FireFox在收到服務器端的數據之后,iframe中的DOM結構:

<html><head></head><body><pre>33|updatePanel|ctl00_Main_UpdatePanel1|...</pre></body></html>

很顯然,這段代碼的意圖是為了在頁面中直接顯示服務器端發送過來的數據。在這種情況下,我們就可以通過“<pre />”元素的innertText屬性(IE 7)或者textContent屬性(FireFox)來直接獲得這段文字。不幸的是,IE6的行為非常奇怪,與前兩者可謂大相徑庭。IE 6會把這段文字按照XML來解析,接著很自然的顯示出錯誤信息,告訴我們這段文本不是一個有效的XML文檔。這非常不合理,因為Response的“Content-Type”是“text/plain”而不是“text/xml”。這是我們要兼容多個瀏覽器時最頭疼的情況。

還記得我們在向客戶段輸出真實的數據前后都調用了WriteScriptBlock方法嗎?下面就是這個方法的實現:

internal static class AjaxFileUploadUtility {internal static void WriteScriptBlock(HttpResponse response, bool begin){string scriptBegin = "<script type='text/javascript' language='javascript'>window.__f__=function(){/*";string scriptEnd = "*/}</script>";response.Write(begin ? scriptBegin : scriptEnd);} }

IE 6和IE 7會將使用<script />來包含的文本作為一段腳本代碼來處理。我們這里在真實的數據兩邊加上了腳本定義的內容,使它成為了客戶端iframe中“__f__”方法的一段注釋,因此我們可以通過調用這個方法的toString函數來獲得這個方法的文本內容。請注意在RenderPageCallback方法中,我們把文本進行了編碼,將“*/”替換為“*//*”,然后再將其發送到客戶端,這么做的目的是使這段文本能夠成為合法的JavaScirpt代碼。

StringBuilder sb = new StringBuilder(); HtmlTextWriter innerWriter = new HtmlTextWriter(new StringWriter(sb)); renderPageCallbackMethodInfo.Invoke(this.PageRequestManager, new object[] { innerWriter, pageControl });writer.Write(sb.Replace("*/", "*//*").ToString());

等一下,我們在這里把異步刷新運行正常時輸出的文本進行了編碼,但是我們在異常情況下的輸出并沒有這么做,不是嗎?沒錯。因為在異常狀況下,錯誤信息會通過Response的Write方法直接輸出(請看PageRequestManager類的OnPageError方法),因此我們無法向前面的代碼那樣獲得它輸出的結果。我們現在只能希望錯誤信息中不要出現“*/”這樣的字符串吧(當然,我們可以使用反射機制來重寫整個邏輯,但是這樣做實在比較復雜)。

下面,我們就要在客戶端的_iframeLoadComplete方法中重新獲取這段文本了:

_iframeLoadComplete : function() {//...try{ var f = iframe.contentWindow.__f__;var responseData = f ? : ;if (responseData.indexOf("\r\n") < 0 && responseData.indexOf("\n") > 0){responseData = responseData.replace(/\n/g, "\r\n");}this._responseData = responseData;this._statusCode = 200;this._responseAvailable = true;}catch (e){this._statusCode = 500;this._responseAvailable = false;}// ... },_parseScriptText : function(scriptText) {var indexBegin = scriptText.indexOf("/*") + 2;var indexEnd = scriptText.lastIndexOf("*/");var encodedText = scriptText.substring(indexBegin, indexEnd);return encodedText.replace(/\*\/\/\*/g, "*/"); },

我們在這里將判斷iframe的window對象中是否存在“__f__”方法,而不是直接判斷瀏覽器的類型來決定下面要做的事情,因為這樣可以帶來更多的瀏覽器兼容性。

FireFox的行為則完全不是這樣的,它依舊使用我們一開始提到的那種DOM結構,把從服務器端得到的文本顯示在iframe中,這種做法比較合理,因為Response的Content-Type為“text-plain”。因此,我們會使用另一種方法來得到這段文本:

_parsePreNode : function(preNode) {if (preNode.tagName.toUpperCase() !== "PRE") throw new Error();return this._parseScriptText(preNode.textContent || preNode.innerText); },

請注意,“_iframeLoadComplete”方法中還有幾行非常重要的代碼:

if (responseData.indexOf("\r\n") < 0 && responseData.indexOf("\n") > 0) {responseData = responseData.replace(/\n/g, "\r\n"); }

由于從服務器端得到的腳本將會被分割為多個部分,每個部分的格式為“length|type|id|content”,因此字符串的長度是在解析文本時非常重要的屬性。因此,我們將會把所有的“\r”替換成“\r\n”,以此保持內容和長度的一致,否則解析過程將會失敗。而且事實上,這樣的替換只會出現在FireFox中。(未完待續)

?

點擊這里下載整個項目

English Version

總結

以上是生活随笔為你收集整理的让UpdatePanel支持文件上传(4):数据传输与解析机制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。