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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入Atlas系列:客户端网络访问基础结构示例(1) - 编写并使用自定义的WebRequestExecutor...

發(fā)布時間:2025/7/14 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入Atlas系列:客户端网络访问基础结构示例(1) - 编写并使用自定义的WebRequestExecutor... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
  WebRequestExecutor是ASP.NET AJAX網(wǎng)絡(luò)訪問基礎(chǔ)結(jié)構(gòu)的唯一修改點。理論上,我們可以使用自定義的WebRequestExecutor來取代默認(rèn)的XMLHttpExecutor。我們要做的,其實只是開發(fā)一個繼承于Sys.Net.WebRequestExecutor類。不過事實上,在實際使用中,Sys.Net.XMLHttpExecutor已經(jīng)足夠用了,真的要自定義,也只需繼承這個類即可。就像接下去的例子一樣。

可是,Sys.Net.XMLHttpExecutor作為一個父類來說,可以說相當(dāng)?shù)牟挥押谩O炔欢嗾f,我們開始吧。在這個例子中,我們將開發(fā)一個TraceExecutor,如果使用了這個Executor,Request和Response的信息都會被打印在頁面上,開發(fā)人員可以把這些內(nèi)容作為一個參考。TraceExecutor非常簡單,代碼也很短。

首先,是構(gòu)造函數(shù)代碼。如下:
Jeffz.Net.TraceExecutor?=?function?Jeffz$Net$TraceExecutor()
{
????Jeffz.Net.TraceExecutor.initializeBase(
this);
}

一般情況下,在這個方法中,會初始化所有的“私有”變量。不過在這里,我們不需要。

然后,我們將覆蓋XMLHttpExecutor的executeRequest方法,我們需要作的,就是將WebRequest對象打印在頁面上。代碼如下:
function?Jeffz$Net$TraceExecutor$executeRequest()
{
????debug.trace(
"<b>Request?sent?at?"?+?new?Date()?+?":</b>");
????debug.dump(
this.get_webRequest(),?"Request");
????
????Jeffz.Net.TraceExecutor.callBaseMethod(
this,?"executeRequest");
}

我在這里使用Debug模式下,為方法起了一個“別名”,在prototype中需要使用一下。自然,我們也需要調(diào)用registerClass,表示類的繼承關(guān)系。代碼如下:
Jeffz.Net.TraceExecutor.prototype?=?
{
????executeRequest?:?Jeffz$Net$TraceExecutor$executeRequest
}
Jeffz.Net.TraceExecutor.registerClass('Jeffz.Net.TraceExecutor',?Sys.Net.XMLHttpExecutor);

等一下,為什么我們就覆蓋executeRequest這一個方法呢?很顯然,我們只是打印出了Request的信息,那么Response呢?我們是不是還需要再覆蓋另一個方法呢?

我們的確應(yīng)該再寫一些代碼,用來將Response信息打印出來,但是我們的做法不是覆蓋XMLHttpExecutor的另一個方法,原因有兩點:
  • XMLHttpExecute作為一個父類,相當(dāng)?shù)夭挥押谩?梢詮拇a里看到,它用來相應(yīng)XMLHttpRequest對象onreadystatechanged的回調(diào)函數(shù)“_onReadyStateChanged”是定義在其構(gòu)造函數(shù)內(nèi)。也就是說,它又使用了Closure,而不是prototype。這樣我們事實上就無法覆蓋那些方法了,如果要繼續(xù)在TraceExecutor上面做文章的話,我們必須寫大量的代碼,這幾乎就相當(dāng)于重新寫了一個WebRequestExecutor。為什么會出現(xiàn)這種情況?是XMLHttpExecutor故意寫成這個樣的嗎?我們來看一下:在XMLHttpRequest代碼的executeRequest方法中,設(shè)置XMLHttpRequest對象onreadystatechanged的代碼是:“this._xmlHttpRequest.onreadystatechanged = this._onReadyStateChanged”,然后在_onReayStateChanged方法中使用了保留在Closure之中的“_this”變量。這個是沒有“Function.createDelegate”時,或者在使用Closure時的寫法,編寫過Windows Live Gadget的朋友們可以回憶一下,在使用官方提供的模版時,是不是在一開始也保留了一個“m_this”變量?這是相似的原因。那么在XMLHttpExecutor里,為什么不使用“Function.createDelegate”方法?估計只有負(fù)責(zé)這部分代碼的開發(fā)人員才知道了。因此,我認(rèn)為這里部分使用了Closure不是故意所為,這更像是負(fù)責(zé)這段代碼的開發(fā)人員一時“神志錯亂”。
  • 即使我們覆蓋了“_onReadyStateChanged”方法,我們還漏了一些別的。如果這個Request超時了呢?如果這個Request被abort了呢?如果我們一一覆蓋這些方法的話,似乎也有些太麻煩了。

因為上面兩個原因(主要是第一個),我們將響應(yīng)Sys.Net.WebRequestManager.completeRequest事件,在這個事件被觸發(fā)時打印Response的信息。代碼如下:
Jeffz.Net.TraceExecutor.traceResponse?=?function?Jeffz$Net$TraceExecutor$traceResponse(response)
{
????debug.trace(
"<b>Response?received?at?"?+?new?Date()?+?":</b>");
????debug.dump(response,?
"Response");
}
Sys.Net.WebRequestManager.add_completedRequest(Jeffz.Net.TraceExecutor.traceResponse);

我們可以嘗試著使用一下,代碼很簡單,將HTML和Javascript一并貼出了。代碼如下:
<asp:ScriptManager?runat="server"?ID="ScriptManager1">
????
<Scripts>
????????
<asp:ScriptReference?Path="Debug.js"?/>
????????
<asp:ScriptReference?Path="TraceExecutor.js"?/>
????
</Scripts>
</asp:ScriptManager>

<asp:UpdatePanel?runat="server"?ID="UpdatePanel1">
????
<Triggers>
????????
<asp:AsyncPostBackTrigger?ControlID="btnRefresh"?/>
????
</Triggers>
????
<ContentTemplate>
????????
<%=?DateTime.Now.ToString("r")?%>
????
</ContentTemplate>
</asp:UpdatePanel>

<asp:Button?runat="server"?ID="btnRefresh"?Text="Refresh"/>

<script?language="javascript">
????Sys.Net.WebRequestManager.set_defaultExecutorType(
"Jeffz.Net.TraceExecutor");
</script>
在這里,需要使用我在《為ASP.NET AJAX 1.0 Beta補充trace和dump功能》里提到的Debug.js來補充ASP.NET AJAX中缺少的trace和dump功能。在代碼的最后會使用Javascript將默認(rèn)的WebRequestExecutor設(shè)為Jeffz.Net.TraceExecutor。

打開頁面,點擊Refresh按鈕,嗯?Request信息不錯,不過Response信息為什么只是這些?
Response?{Jeffz.Net.TraceExecutor}
+_webRequest?{Sys.Net.WebRequest}
+_resultObject:?null
+_xmlHttpRequest?{Object}
+_responseAvailable:?true
+_timedOut:?false
+_timer:?null
+_aborted:?false
+_started:?true

原因在于,由于缺少了了Type Descriptor,debug.dump方法只會將該對象上附屬的“值”(例如:this._started)打印出來,而不會調(diào)用任何方法。而在XMLHttpExecutor中,許許多多方法(各種屬性的get方法)是直接將消息委托給XMLHttpRequest對象,而不是將信息保留在XMLHttpExecutor附屬“值”上,因此,我們得到的只能是這些無用的信息了。

那么我們該怎么做?那么就為Response對象補充一個Type Descriptor。這里的Response對象其實就是Jeffz.Net.TraceExecutor類的實例,因此我們需要為該類添加一個Type Descriptor。代碼如下:
Jeffz.Net.TraceExecutor.descriptor?=
{
????properties:
????[
????????{name:?'started',?type:?Boolean?},
????????{name:?'timedOut',?type:?Boolean?},
????????{name:?'aborted',?type:?Boolean?},
????????{name:?'responseAvailable',?type:?Boolean?},
????????{name:?'responseData',?type:?String?},
????????{name:?'statusCode',?type:?Number?},
????????{name:?'statusText',?type:?String?}
????]
}

這是RTM中Type Descriptor的表示方式。可以發(fā)現(xiàn)我在這里只添加了部分,而不是全部的屬性。例如缺少了object屬性,為什么呢?在XMLHttpExecutor中g(shù)et_object方法是這樣定義的:
function?Sys$Net$WebRequestExecutor$get_object()?{
????
///?<value></value>
????if?(arguments.length?!==?0)?throw?Error.parameterCount();

????
if?(!this._resultObject)?{
????????
this._resultObject?=?Sys.Serialization.JavaScriptSerializer.deserialize(this.get_responseData());
????}

????
return?this._resultObject;
}

我們可以發(fā)現(xiàn),這段邏輯并沒有判斷responseData的合法性,如果它不是一個正確的JSON字符串,就會拋出異常。如果一定要在Type Descriptor中定義object屬性的話,那么我們還必須在TraceExecutor中覆蓋XMLHttpRequest的object屬性。作為一個沒有多少使用價值的演示,我們就不作得如此“仁至義盡”了。:)

現(xiàn)在我們再來看一下打印出來的內(nèi)容:




點擊這里下載示例代碼。

轉(zhuǎn)載于:https://www.cnblogs.com/JeffreyZhao/archive/2006/10/30/Inside_Atlas_Series__Client_Communication_Architecture__Sample_1.html

總結(jié)

以上是生活随笔為你收集整理的深入Atlas系列:客户端网络访问基础结构示例(1) - 编写并使用自定义的WebRequestExecutor...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。