WCF常见问题(1) -- WebService/WCF Session Cookie

简介: 原文: WCF常见问题(1) -- WebService/WCF Session Cookie 在.net 3.0推出WCF之前使用的WebService,有的应用有使用Session保持一些信息,在不同的WebMethod中共享存储信息。
原文: WCF常见问题(1) -- WebService/WCF Session Cookie

在.net 3.0推出WCF之前使用的WebService,有的应用有使用Session保持一些信息,在不同的WebMethod中共享存储信息。比如:保持登陆用户的信息等。其原理是应用ASP.NET兼容模式,利用HttpContext来保持请求的上下文。

为了显示WebService/WCF不同应用下的Session/Cookie应用,这里分别创建两个Service应用:一个是WebService Application(.net 4.0下没有此模板,只有在.net 3.5以下版本中有),一个是WCFService Application(IIS宿主的WCF应用)
整体solution图:


1. WebService Application(*.asmx) + .net 2.0 Client Proxy
可以看到 Login 方法里将登录的 userName 保存在 Session 里。在 GetUserName 方法返回 Session 中的数据。
[WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [System.ComponentModel.ToolboxItem(false)] public class Service1 : System.Web.Services.WebService { [WebMethod(EnableSession=true)] public void Login(string user) { var session = HttpContext.Current.Session; session["user"] = user; HttpContext.Current.Response.Cookies.Add(new HttpCookie("user", user)); } [WebMethod(EnableSession = true)] public string GetUserName() { return HttpContext.Current.Session["user"] as string; } }
先来看看 .net 2.0 中的客户端如何保持 Session 的。
ASP.NET 中的客户端也就是浏览器端会通过Cookie来保持 Session。所以对于 WebService 的客户端需要自己去维护一个 CookieContainer。(服务端需要没一个WebMethod都需要设定EnableSession=true)
CookieContainer cookieContainer = new CookieContainer();
而每次调用都必须添加这个cookieContainer的实例。
PS: .net 3.5里仍然可以使用.net 2.0生成客户端:Add Service Reference -> Advance -> Add Web Reference

添加完WebService Reference后客户端调用:
using (var svc = new MyWebSvc.Service1()) { svc.CookieContainer = cookieContainer; svc.Login(textBox1.Text); }
再一次调用:
using (var svc = new MyWebSvc.Service1()) { svc.CookieContainer = cookieContainer; label1.Text = svc.GetUserName(); }
OK,现在的客户端实现了cookie的保持,每次调用Service方法时,Service会携带之前的cookie信息,则在服务端则能识别调用的Session而返回对应的数据。

2. WebService Application(*.asmx) + .net 3.5 Client Proxy
服务端代码没有变化,客户端引用则修改为 Add Service Reference .net 3.5 生成客户端代理。
这次生成的客户端代理中已经找不到 svc 中的 CookieContainer 属性,难道不能保持客户端 cookie 了吗?
检查客户端生成 app.config (.net 3.5里的WebService原来使用的是basicHttpBinding)
<system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="Service1Soap" allowCookies="false" ......
原来 allowCookies 默认设为 false 了,我们把它改为:true 就OK了。
using (var svc = new MyWCFWebSvc.Service1SoapClient()) { svc.Login(textBox1.Text); }
再次调用:
using (var svc = new MyWCFWebSvc.Service1SoapClient()) { label1.Text = svc.GetUserName(); }

3. WCF Service Application(*.svc) + .net 3.5 Client Proxy
WCF的ServiceContract
[ServiceContract] public interface IService1 { [OperationContract] string GetUserName(); [OperationContract] void Login(string user); }
Service的实现,类似上面的WebMethod
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class Service1 : IService1 { public void Login(string user) { var session = HttpContext.Current.Session; session["user"] = user; HttpContext.Current.Response.Cookies.Add(new HttpCookie("user", user)); } public string GetUserName() { return HttpContext.Current.Session["user"] as string; } } 
WCF Service Application的工程模板中,默认是没有启用ASP.NET兼容模式的,这个时候直接调用 HttpContext 将返回 null。
所以需要设置 AspNetCompatibilityRequirements 特性:
1)[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
2)服务端配置文件也需要修改,在 <system.serviceModel> 节点中,添加如下配置:
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
客户端生成的配置文件 app.config 也同样需要设置

<system.serviceModel>
        <bindings>
              <wsHttpBinding>
                  <binding name="WSHttpBinding_IService1" allowCookies="true" ......

 

运行效果:

 

上面的代码中,cookie只在应用程序的生存周期内有效,也就是说当程序关闭,cookie就失效了。服务端也就不能取得对应的session信息了。如果一定要实现类似浏览器浏览网页,今天登陆明天再开还能有效呢?那就得自己来维持这个CookieContainer了,也就是说持久化这个对象。不过遗憾的是在.net3.0以上版本直接添加Service Reference的本地代理中,并没有CookieContainer属性。只能选择使用.net2.0生成客户端代理。持久化CookieContainer的代码如下:
 CookieContainer cookieContainer = new CookieContainer(); private void Form1_Load(object sender, EventArgs e) { var cookieFile = "MyCookie.dat"; if (File.Exists(cookieFile)) { using (var fs = File.OpenRead(cookieFile)) { var bf = new BinaryFormatter(); cookieContainer = bf.Deserialize(fs) as CookieContainer; } } } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { var cookieFile = "MyCookie.dat"; using (var fs = File.OpenWrite(cookieFile)) { var bf = new BinaryFormatter(); bf.Serialize(fs, cookieContainer); } } 

 

目录
相关文章
|
2月前
|
存储 自然语言处理 API
Session、cookie、token有什么区别?
Session、cookie、token有什么区别?
24 1
|
3月前
|
存储 开发框架 NoSQL
ASP.NET WEB——项目中Cookie与Session的用法
ASP.NET WEB——项目中Cookie与Session的用法
41 0
|
3月前
|
存储 安全 API
Cookie,Session和Token
Cookie,Session和Token
|
4天前
|
存储 安全 Java
JavaWeb中的Session和Cookie
本文介绍了JavaWeb中的会话跟踪技术,主要讨论了Cookie和Session的概念、用途、设置与获取方法以及生命周期。Cookie是客户端技术,用于在用户浏览器中存储信息,通常用于保持用户登录状态,有效期可设置。Session则保存在服务器端,用于跟踪用户状态,例如登录信息,生命周期可通过设置最大不活动时间控制。两者之间的主要区别在于数据存储位置和安全性,Cookie数据在客户端,可能存在安全风险,而Session数据在服务器端,相对较安全但会占用服务器资源。
|
8天前
|
存储 搜索推荐 安全
【Cookie和Session辨析】
【Cookie和Session辨析】
11 2
|
14天前
|
存储 缓存 安全
【PHP开发专栏】PHP Cookie与Session管理
【4月更文挑战第30天】本文介绍了PHP中的Cookie和Session管理。Cookie是服务器发送至客户端的数据,用于维持会话状态,可使用`setcookie()`设置和`$_COOKIE`访问。Session数据存于服务器,更安全且能存储更多数据,通过`session_start()`启动,`$_SESSION`数组操作。根据需求选择Cookie(跨会话共享)或Session(单会话存储)。实战中常组合使用,如Cookie记住登录状态,Session处理购物车。理解两者原理和应用场景能提升Web开发技能。
|
17天前
|
存储 安全 前端开发
禁用Cookie后Session还能用吗?
禁用Cookie后Session还能用吗?
24 1
|
17天前
|
Java
Cookie和Session
Cookie和Session
19 0
|
29天前
|
存储 JSON 安全
|
1月前
|
存储 前端开发 数据安全/隐私保护
网站开发--Cookie 和 Session 的工作流程
网站开发--Cookie 和 Session 的工作流程
18 0