WebServices 基礎知識

1. 有關生存期的補充

正常情況下,每次調用 WebMethod,服務器都會創建一個新的 WebService 對象,即便客戶端使用同一個代理對象多次調用 WebMethod。

而我們一旦調用了有緩存標記的 WebMethod,只要未超出緩存期,WebService 對象都不會被重新創建。在緩存期內調用沒有緩存標記的 WebMethod,也會繼續使用該 WebService 對象。有太多因素讓這個緩存機制變得不那么可靠,因此我們不能奢望用緩存標記來維持特定的對象狀態,況且緩存機制的設計初衷也只是為了快速輸出那些比較穩定非常大的數據。

基于多用戶并發調用這個環境,WebService 本身最好設計成無狀態對象,我們可以使用 Session 和 Application 來保持特定的狀態信息。

2. 異步調用

網上很多人在寫有關 .net 2.0 的文章時,都喜歡用“優雅”這個詞。的確,在 2.0 中編譯器和代碼生成器為我們封裝了很多羅嗦的東西,諸如匿名方法、委托推斷等等,當然還有這 WebService 的異步調用。我們不用再寫那些個 BeginXXX、EndXXX 了,基于事件驅動的異步機制會自動為每個 WebMethod 生成一個 XXXAsync 的異步方法和 XXXCompleted 事件,我們只需調用該方法,并處理該事件即可完成異步操作,當真是優雅了不少。不要小看 2.0 的這些封裝,我們編寫的代碼越少意味著出錯的幾率越小。

下面的示例中,我們使用了匿名方法來處理事件,看上去更簡潔了些。

WebServices.cs

[WebService(Namespace = "http://www.rainsts.net/", Description="我的Web服務")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
??[WebMethod]
??public string HelloWorld()
??{
????return "Hello World!";
??}
}


Client.cs

WebService ws = new WebService();
ws.HelloWorldCompleted += delegate(object sender, HelloWorldCompletedEventArgs e)
{
??Console.WriteLine(e.Result);
};

ws.HelloWorldAsync("xxx");


3. 緩存

WebMethodAttribute.CacheDuration 為 WebService 提供了緩存申明機制。通過添加該標記,我們可以緩存輸出結果。不過緩存機制會影響 WebService 的生存期(見上)。

WebServices.cs

[WebService(Namespace = "http://www.rainsts.net/", Description="我的Web服務")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
??[WebMethod(CacheDuration=10)]
??public DateTime TestCache()
??{
????return DateTime.Now;
??}
}


Client.cs

WebService ws = new WebService();

for (int i = 0; i < 20; i++)
{
??Console.WriteLine("{0}:{1}", i + 1, ws.TestCache());
??Thread.Sleep(1000);
}


4. 保持狀態

.NET WebService 是建立在 ASP.NET 基礎上,在 WebService 中我們同樣可以訪問 Session、User、Application 等上下文對象,不過在某些使用細節上可能有所不同。

由于 WebService 客戶端代理對象可能應用于 ConsoleApplication、WinForm 或 WebForm 等環境,而 Session 又必須通過 Cookie 來保存唯一的 SessionID,因此我們必須使用 CookieContainer 創建 Cookie 容器來保存 WebService 返回的 Session 信息,否則每次調用的 SessionID 都不同,自然無法使用 Session 來保存狀態了。

創建容器對象后,必須將其引用賦值給代理對象的 CookieContainer 屬性。在第一次調用 SessionEnabled WebMethod 后,該容器將持有 Session Cookie 信息。如果需要在多個代理對象中調用 SessionEnabled WebMethod,那么它們必須持有同一個 Cookie 容器對象。

WebServices.cs

[WebService(Namespace = "http://www.rainsts.net/", Description="我的Web服務")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
??[WebMethod(EnableSession = true)]
??public string TestSession()
??{
????string s = "TestSession";
????object o = Session[s];
????int i = o != null ? (int)o : 0;

????++i;
????Session[s] = i;

????return Session.SessionID.ToString() + ":" + i;
??}
}


Client.cs

WebService ws = new WebService();

// 創建Cookie容器,保持SessionID。否則每次調用的 SessionID 都不同。
CookieContainer cookies = new CookieContainer();
ws.CookieContainer = cookies;

for (int i = 0; i < 10; i++)
{
??Console.WriteLine("{0}:{1}", i + 1, ws.TestSession());
}


至于 Application 的使用和 WebForm 中基本沒有什么區別。

WebServices.cs

[WebService(Namespace = "http://www.rainsts.net/", Description="我的Web服務")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
??[WebMethod]
??public DateTime TestApplicationState()
??{
????object o = Application["TestApplicationState"];
????if (o == null)
????{
??????o = DateTime.Now;
??????Application["TestApplicationState"] = o;
????}

????return (DateTime)o;
??}
}


Client.cs

for (int i = 0; i < 10; i++)
{
??WebService ws = new WebService();
??Console.WriteLine("{0}:{1}", i + 1, ws.TestApplicationState());
??Thread.Sleep(1000);
}


5. SoapHeader

SoapHeader 多數情況下用來傳遞用戶身份驗證信息,當然它的作用遠不止如此,有待于在實際應用中發掘。

SoapHeader 缺省情況下由客戶端代理對象發送給 WebService,當然我們可以通過 WebMethodAttribute.Direction 來改變傳送方向。

SoapHeader 使用步驟:

(1) 創建繼承自 System.Web.WebServices.SoapHeader 的自定義 SoapHeader 類型。
(2) 在 WebService 中創建擁有 public 訪問權限的自定義 SoapHeader 字段。
(3) 在需要使用 SoapHeader 的 WebMethod 上添加 SoapHeaderAttribute 訪問特性。SoapHeaderAttribute 構造必須指定 memberName 參數,就是我們在第二步中申明的字段名稱。
(4) 生成器會自動為客戶端生成同名的自定義 SoapHeader 類型,只不過比起我們在 WebService 端創建的要復雜一些。同時還會為代理類型添加一個 soapheaderValue 屬性。

在下面的演示代碼,客戶端將傳遞一個自定義 MyHeader 到 WebService。請注意,我們盡管在 WebService 中申明了 MyHeader 字段,但并沒有創建對象實例,這是因為客戶端傳遞過來的 XML 中包含了 SoapHeader 信息,基礎結構會自動解析并創建對象實例,然后賦值給 my 字段。至于客戶端,自然需要創建一個 MyHeader 對象實例,并賦值給 WebService.MyHeaderValue 屬性。SoapHeaderAttribute.Direction 缺省就是 In,下面例子中的 "Direction = SoapHeaderDirection.In" 可以省略。

WebServices.cs

public class MyHeader : SoapHeader
{
??public string Username;
??public string Password;
}

[WebService(Namespace = "http://www.rainsts.net/", Description="我的Web服務")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
??public MyHeader my;

??[WebMethod]
??[SoapHeader("my", Direction = SoapHeaderDirection.In)]
??public void TestSoapHeadIn()
??{
????System.Diagnostics.Debug.Write(my.Username);
????System.Diagnostics.Debug.Write(my.Password);
??}
}


Client.cs

WebService ws = new WebService();

MyHeader head = new MyHeader();
head.Username = "u2";
head.Password = "p2";

ws.MyHeadValue = head;
ws.TestSoapHeadIn();


我們改寫一下,將傳遞方向改為從 WebService 到客戶端。自然我們需要調整 "Direction = SoapHeaderDirection.Out",在 WebMethod 中我們還必須創建 MyHeader 實例,因為這次我們不會接受到客戶端傳遞的 SoapHeader 了。客戶端代理對象調用 WebMethod 后就可以使用 MyHeaderValue 屬性訪問其內容了。

WebServices.cs

public class MyHeader : SoapHeader
{
??public string Username;
??public string Password;
}

[WebService(Namespace = "http://www.rainsts.net/", Description="我的Web服務")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
??public MyHeader my;

??[WebMethod]
??[SoapHeader("my", Direction = SoapHeaderDirection.Out)]
??public void TestSoapHeadOut()
??{
????my = new MyHeader();
????my.Username = "u1";
????my.Password = "p1";
??}
}


Client.cs

WebService ws = new WebService();
ws.TestSoapHeadOut();

Console.WriteLine(ws.MyHeaderValue.Username);
Console.WriteLine(ws.MyHeaderValue.Password);


6. 異常

ASP.NET WebService 通過 Fault XML 元素來傳遞異常信息,客戶端代理對象會生成一個 SoapException 的異常,并使用 Fault XML 信息填充其相關屬性,諸如 Message 等。另外我們可以對 WebService 進行異常包裝,除了傳遞 Exception Message 外,還可以傳遞一些錯誤狀態代碼,以便客戶端用戶做進一步處理。

WebServices.cs

[WebService(Namespace = "http://www.rainsts.net/", Description="我的Web服務")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class WebService : System.Web.Services.WebService
{
??[WebMethod]
??public void TestException()
??{
????try
????{
??????throw new Exception("aaa...");
????}
????catch (Exception e)
????{
??????throw new SoapException(e.Message, new System.Xml.XmlQualifiedName("ErrorCode01"), e);
????}
??}
}


Client.cs

WebService ws = new WebService();

try
{
??ws.TestException();
}
catch (System.Web.Services.Protocols.SoapException e)
{
??Console.WriteLine(e.Message);
??Console.WriteLine(e.Code.Name);
}
原文地址:http://www.rainsts.net/article.asp?id=282

轉載于:https://www.cnblogs.com/wfwup/archive/2009/12/02/1615186.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/276285.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/276285.shtml
英文地址,請注明出處:http://en.pswp.cn/news/276285.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

sass和compass基礎用法

一、基本命令 sass都是通過gem安裝&#xff0c;以下是一些基礎的命令移除ruby的鏡像地址 gem sources --remove https://rubygems.org/添加淘寶的鏡像 gem source -a http://ruby.taobao.org查看鏡像 gem source -v單文件轉換命令 sass style.scss style.css單文件監聽命令&am…

字節面試官:如何實現Ajax并發請求控制

偷偷告訴你&#xff0c;點此抽獎送紅包還送3本比紅寶書還貴的書實現一個批量請求函數 multiRequest(urls, maxNum)&#xff0c;要求如下&#xff1a; ? 要求最大并發數 maxNum ? 每當有一個請求返回&#xff0c;就留下一個空位&#xff0c;可以增加新的請求 ? 所有請求完成后…

Jquery 中 ajaxSubmit使用講解

轉載鏈接&#xff1a;http://blog.csdn.net/h70614959/article/details/8810270 1 引入依賴腳本 <script type"text/javascript" src"/js/jquery/jquery.form.js"></script> //ajaxForm 依賴腳本<script type"text/javascript"…

接口與抽象類

接口中的屬性 默認是 public static final類型 就算你不加 默認也是存在 方法默認都是public abstract類型 不加默認也存在 比如 interface K { String abc"sdfd"; void add() throws Exception; } 實際上編譯時 是這樣 interface K { Public static final String a…

制造行業電子化簽約及印控一體化解決方案

當生產“智造化”、營銷“數字化”成為趨勢&#xff0c;生產制造型企業如何實現產品生產-銷售全流程提速降本&#xff1f;生產制造型企業為了在生產、營銷環節降低成本、提升效率&#xff0c;經營模式上常有如下特征&#xff1a;? 原料導向&#xff0c;多點協同生產&#xff1…

python 點擊按鈕采集圖片_python多線程采集圖片

cmd中運行>python untitled2.py 圖片的網站import requestsimport threadingfrom bs4 import BeautifulSoupimport sysimport osif len(sys.argv) ! 2:print("Usage : " )print(" python main.py [URL]" )exit(1)# config-starturl sys.argv[1]thre…

一起手寫Vue3核心模塊源碼,掌握閱讀源碼的正確方法

最近和一個獵頭聊天&#xff0c;說到現在前端供需脫節的境況。一方面用人方招不到想要的中高級前端&#xff0c;另一方面市場上有大量初級前端薪資要不上價。特別是用 Vue 框架的&#xff0c;因為好上手&#xff0c;所以很多人將 Vue 作為入門框架&#xff0c;但學得深的人并不…

jquery|javascript 回車事件

轉載鏈接&#xff1a;http://www.cnblogs.com/wenbo/archive/2011/08/20/2147014.html 轉載鏈接: http://www.2cto.com/kf/201202/119741.html jquery實現回車事件&#xff0c;代碼如下&#xff1a; 全局&#xff1a; $(function(){ document.onkeydown function(e){…

【Vegas原創】ASP 0131 不允許父路徑的解決

現象&#xff1a; Active Server Pages 錯誤 ASP 0131 不允許的父路徑 /admin/login.asp&#xff0c;行 2 包含文件 ../include/config.asp 不能用 .. 表示父目錄。 解決方案&#xff1a; IIS6>站點屬性>主目錄>配置>選項>啟用父路徑 轉載于:https://www.cnblog…

騰訊正式宣布成立技術委員會,要對組織架構下狠手

2019 年伊始&#xff0c;社交巨人騰訊正式宣布成立技術委員會&#xff0c;計劃在未來發力內部代碼的開源和協同&#xff0c;投入更多資金和精力在技術建設上。BAT 三家里一直被詬病技術建設落后的騰訊&#xff0c;終于開始補足自己的短板。這會對騰訊自身帶來什么&#xff1f;又…

2020 前端技術發展回顧

大家好&#xff0c;我是若川&#xff0c;今天給大家分享一篇來自阿里媽媽前端快爆的好文。另外&#xff0c;偷偷告訴你&#xff0c;截止今晚9點 點此抽獎送紅包還送3本比紅寶書還貴的書可以點擊文章末尾閱讀原文直達知乎鏈接&#xff0c;以下是正文2020 終究是一個不平凡的一年…

php驗證碼函數 使用imagestring() imagefttext()設置字體大小

轉載路徑&#xff1a;http://hi.baidu.com/asdasd_cn/item/62977d1e26ca36e85e53b142 生成驗證碼圖片的兩個函數 第一個是用imagestring bool imagestring ( resource $image , int $font , int $x , int $y , string $s , int $col ) imagestring() 用 col …

提取地圖中道路_非機器學習方法·從遙感影像中提取道路

本科低年級曾經做過一個提取道路線的題目。提供的數據&#xff1a;老師給我們了一幅學校周邊地區的影像&#xff0c;包括RGBInfrared四個波段。一開始使用的方法&#xff1a;當時尚青澀的我和小伙伴們一起使用KMEANS、閾值分割等等方法試圖將那道路從影像中分離出來。遇到的問題…

圖片尺寸自適應

圖片尺寸自適應 οnlοad"javascript:if(this.height>this.width){this.height100}else{this.width100} 轉載于:https://www.cnblogs.com/TangZhongxin/archive/2009/12/14/3942483.html

第一章知識點

第一章知識點 一&#xff1a;SQL語言 1&#xff0c;結構化查詢語言&#xff0c;是關系數據庫的標準語言 2&#xff0c;分類&#xff1a; 2.1&#xff1a;數據操作語言&#xff1a;DML&#xff1b;包括&#xff1a;即增刪查改&#xff1b;insert&#xff0c;update&#xff0c;d…

2021年,推薦這幾個優質公眾號碎片化學習

2021 年了&#xff0c;前端技術日新月異&#xff0c;發展迅速&#xff0c;前端公眾號是不是感覺越來越多了&#xff1f;在著辭舊迎新之際&#xff0c;這里盤點幾個前端開發工程師 2021 年必須關注的優質公眾號&#xff0c;希望對你有所幫助。大家可以像我一樣&#xff0c;利用碎…

php 處理表單里面的 單雙引號

轉載鏈接&#xff1a;http://developer.51cto.com/art/200911/165392.htm 我們今天要向大家介紹的是PHP magic_quotes_gpc的具體使用方法。大家都知道在PHP中一個特殊的函數魔術函數&#xff0c;它在引用的過程中只有在傳遞$_GET,$_POST,$_COOKIE時才會發生作用。 PHP函數preg…

阿里云插件新版發布,多特性助力提升開發者體驗

好消息&#xff01;阿里云 Cloud Toolkit 新版本于近日正式發布&#xff0c;推出了面向 IntelliJ 和 Eclipse 兩個平臺的新款插件&#xff0c;多個重大特性&#xff0c;持續提升開發者體驗&#xff0c;本文將帶大家快速預覽該新版本。 本文只挑選下面三個重大特性進行解讀&…

海鷗表表帶太長了怎么拆_表帶安裝,表帶太長了,怎么拆解和安裝?

表帶太長了&#xff0c;怎么拆解和安裝&#xff1f;1、準備拆表帶前請看清楚表帶背面的箭頭。2、有箭頭的帶粒是可拆卸的。3、擰松拆帶器把手&#xff0c;將表帶放入表槽&#xff0c;并保持拆帶器的鋼針對準針孔&#xff0c;如圖二&#xff0c;且拆帶器的鋼針順著箭頭的指示方向…

python類庫31[文件和目錄os+os.path+shutil]

一 常用函數 os模塊 os.sep 表示默認的文件路徑分隔符&#xff0c;windows為\, linux為/os.walk(spath): 用來遍歷目錄下的文件和子目錄os.listdir(dirname)&#xff1a;列出dirname下的目錄和文件os.mkdir() &#xff1a; 創建目錄os.makedirs(): 創建目錄&#xff0c;包含中間…