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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

WCF技术剖析之五:利用ASP.NET兼容模式创建支持会话(Session)的WCF服务

發布時間:2024/4/15 asp.net 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WCF技术剖析之五:利用ASP.NET兼容模式创建支持会话(Session)的WCF服务 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
原文:WCF技術剖析之五:利用ASP.NET兼容模式創建支持會話(Session)的WCF服務

在《基于IIS的WCF服務寄宿(Hosting)實現揭秘》中,我們談到在采用基于IIS(或者說基于ASP.NET)的WCF服務寄宿中,具有兩種截然不同的運行模式:ASP.NET并行(Side by Side)模式和ASP.NET兼容模式。對于前者,WCF通過HttpModule實現了服務的寄宿,而對于后者,WCF的服務寄宿通過一個HttpHandler實現。只有在ASP.NET兼容模式下,我們熟悉的一些ASP.NET機制才能被我們使用,比如通過HttpContext的請求下下文;基于文件或者Url的授權;HttpModule擴展;身份模擬(Impersonation)等。

由于在ASP.NET兼容模式下,ASP.NET采用與.aspx Page完全一樣的方式處理基于.svc的請求,換言之,我們就可以借助當前HttpContext的SessionState維護會話狀態,進而創建一個支持會話的WCF Service。接下來,我們就通過一個簡單的例子,一步步地創建這樣的會話服務。本案例采用如圖1所示的3層結構。 (Source Code從這里下載)

? 圖1 ASP.NET兼容模式案例應用結構

?

步驟一、定義服務契約:ICalculator

案例依然沿用計算服務的例子,不過通過原來直接與傳入操作數并得到運算結果的方式不同,為了體現會話狀態的存在,我們將本案例的WCF服務定義成“累積計算服務”:保留上一次運算的結果,并將其作為后續運算的操作數。為此,定義了如下一個接口作為服務契約:前面4個操作代表基本的加、減、乘、除運算,計算結果通過GetResult方法獲得。

1: using System.ServiceModel; 2: namespace Artech.AspCompatibleServices.Contracts 3: { 4: [ServiceContract] 5: public interface ICalculator 6: { 7: [OperationContract] 8: void Add(double x); 9: [OperationContract] 10: void Subtract(double x); 11: [OperationContract] 12: void Multiply(double x); 13: [OperationContract] 14: void Divide(double x); 15: [OperationContract] 16: double GetResult(); 17: } 18: }

步驟二、實現服務:CalculatorService

服務的實現和.svc都定義在一個ASP.NET Web站點項目中。對于定義在 CalculatorService中的每次運算,先通過HttpContext從SessionState中取出上一次運算的結果,完成運算后再將新的運算結果保存到SessionState中。通過在CalculatorService上應用AspNetCompatibilityRequirementsAttribute實現對ASP.NET兼容模式的支持。

1: using System.ServiceModel.Activation; 2: using System.Web; 3: using Artech.AspCompatibleServices.Contracts; 4: [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 5: public class CalculatorService : ICalculator 6: { 7: public void Add(double x) 8: { 9: HttpContext.Current.Session["__Result"] = GetResult() + x; 10: } 11: public void Subtract(double x) 12: { 13: HttpContext.Current.Session["__Result"] = GetResult() - x; 14: } 15: public void Multiply(double x) 16: { 17: HttpContext.Current.Session["__Result"] = GetResult() * x; 18: } 19: public void Divide(double x) 20: { 21: HttpContext.Current.Session["__Result"] = GetResult() / x; 22: } 23: public double GetResult() 24: { 25: if (HttpContext.Current.Session["__Result"] == null) 26: { 27: HttpContext.Current.Session["__Result"] = 0.0; 28: } 29: return (double)HttpContext.Current.Session["__Result"]; 30: } 31: }

下面是CalculatorService對應的.svc的定義和Web.config。為了簡潔,在<@ServiceHost%>指令中,僅僅設置一個必需屬性Service。對于ASP.NET兼容模式的支持,配置<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>必不可少。

1: <?xml version="1.0"?> 2: <configuration> 3: <system.serviceModel> 4: <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> 5: <services> 6: <service name="CalculatorService"> 7: <endpoint binding="wsHttpBinding" contract="Artech.AspCompatibleServices.Contracts.ICalculator" /> 8: </service> 9: </services> 10: </system.serviceModel> 11: </configuration>

步驟三、創建客戶端:Client

CalculatorService的客戶端應用通過一個Console應用程序模擬,其服務調用方式并無特別之處,下面是相關的代碼和配置。

1: using System; 2: using System.ServiceModel; 3: using Artech.AspCompatibleServices.Contracts; 4: namespace Artech.AspCompatibleServices.Clients 5: { 6: class Program 7: { 8: static void Main(string[] args) 9: { 10: using (ChannelFactory<ICalculator> channelFactory = new ChannelFactory<ICalculator>("CalculatorService")) 11: { 12: ICalculator proxy = channelFactory.CreateChannel(); 13: Console.WriteLine("初始值為: {0}", proxy.GetResult()); proxy.Add(1); 14: Console.WriteLine("Add(3)", proxy.GetResult()); 15: Console.WriteLine("運算結果為: {0}", proxy.GetResult()); proxy.Multiply(10); 16: Console.WriteLine("Multiply(10)", proxy.GetResult()); Console.WriteLine("運算結果為: {0}", proxy.GetResult()); proxy.Subtract(2); 17: Console.WriteLine("Subtract(2)", proxy.GetResult()); Console.WriteLine("運算結果為: {0}", proxy.GetResult()); 18: } Console.Read(); 19: } 20: } 21: }

?

1: <?xml version="1.0" encoding="utf-8" ?> 2: <configuration> 3: <system.serviceModel> 4: <client> 5: <endpoint address="http://localhost/AspCompatibleServices/CalculatorService.svc" 6: binding="wsHttpBinding" contract="Artech.AspCompatibleServices.Contracts.ICalculator" 7: name="CalculatorService"/> 8: </client> </system.serviceModel> 9: </configuration>

但是,但我們運行客戶端的程序,輸出的結果并不像我們希望的那樣。從下面的結果可以看出,每次通過GetResult()方法得到的結果都是0,也就是說,服務端并沒有將運算結果保存下來。

1: 初始值為:0 2: Add(3)運算結果為:0 3: Multiply(10)運算結果為:0 4: Subtract(2)運算結果為:0

允許Cookie傳遞

要解釋這個問題,得從Session的實現機制說起。眾所周知,HTTP是無狀態(Stateless)的傳輸協議,對服務端來說,它收到的每個HTTP請求都是全新的請求。ASP.NET會話(Session)的實現很簡單,就是讓每次HTTP請求攜帶Session的識別信息(Session ID),那么服務就可以根據此信息判斷請求來自哪個客戶端了。關于Session識別信息的保存,ASP.NET有兩種方式:Cookie和URL,前者將其放到Cookie中,每次HTTP請求將會攜帶該Cookie的值,后者則將其作為請求URL的一部分。一般情況下采用基于Cookie的實現機制,如果Cookie禁用則采用后者。

那么對于ASP.NET兼容模式下的WCF也一樣,要想讓服務端能夠識別會話,就需要讓每個服務調用的HTTP請求攜帶Session的識別信息,我們也可以通過傳遞Cookie的方式來解決這個問題。對于WCF來說,Cookie傳遞能夠通過Binding來控制,對于WsHttpBinding來說,默認情況下并不允許Cookie的傳遞。我們可以通過WsHttpBinding的AllowCookies來控制是否允許傳遞Cookie,該屬性可以通過配置進行設置。為此,我們對客戶端的配置進行了如下的修改。再次運行我們的案例程序,將會得到你期望的輸出。

1: <?xml version="1.0" encoding="utf-8" ?> 2: <configuration> 3: <system.serviceModel> 4: <client> 5: <endpoint address="http://localhost/AspCompatibleServices/CalculatorService.svc" 6: binding="wsHttpBinding" contract="Artech.AspCompatibleServices.Contracts.ICalculator" 7: name="CalculatorService" bindingConfiguration="CookieAllowableBinding"/> 8: </client> 9: <bindings> 10: <wsHttpBinding> 11: <binding name="CookieAllowableBinding" allowCookies="true"/> 12: </wsHttpBinding> 13: </bindings> 14: </system.serviceModel> 15: </configuration>

客戶端輸出結果:

1: 初始值為:0 2: Add(3)運算結果為:3 3: Multiply(10)運算結果為:30 4: Subtract(2)運算結果為:28 作者:Artech
出處:http://artech.cnblogs.com
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。

總結

以上是生活随笔為你收集整理的WCF技术剖析之五:利用ASP.NET兼容模式创建支持会话(Session)的WCF服务的全部內容,希望文章能夠幫你解決所遇到的問題。

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