WCF常见问题(1) -- WebService/WCF Session Cookie
原文: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);
}
}
WCF常见问题(1) -- WebService/WCF Session Cookie的更多相关文章
- 关于通信的关键词UDP/(TCP/IP)/IPC/RPC/.NET Remoting/WebService/WCF/Http 系列
OSI七层和TCP/IP四层的关系 1.1 OSI引入了服务.接口.协议.分层的概念,TCP/IP借鉴了OSI的这些概念建立TCP/IP模型. 1.2 OSI先有模型,后有协议,先有标准,后进行实践: ...
- .Net remoting, Webservice,WCF,Socket区别
传统上,我们把计算机后台程序(Daemon)提供的功能,称为"服务"(service).比如,让一个杀毒软件在后台运行,它会自动监控系统,那么这种自动监控就是一个"服务& ...
- 不用webservice wcf提供服务,用Rest更轻量
从2005年开始就开始有基于服务的开发方式,到08年时候 微软和sun等公司都已经提供了很多基于服务的开发框架 . 微软 .net 平台的基于服务的框架主要有:.NET Remoting.webser ...
- Webservice WCF WebApi 前端数据可视化 前端数据可视化 C# asp.net PhoneGap html5 C# Where 网站分布式开发简介 EntityFramework Core依赖注入上下文方式不同造成内存泄漏了解一下? SQL Server之深入理解STUFF 你必须知道的EntityFramework 6.x和EntityFramework Cor
Webservice WCF WebApi 注明:改编加组合 在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web API.在.net平台下, ...
- session cookie原理及应用
一.术语session在我的经验里,session这个词被滥用的程度大概仅次于transaction,更加有趣的是transaction与session在某些语境下的含义是相同的. session,中 ...
- C#调用WebService时插入cookie
SOAPUI插入Cookie的方法 SOAP插入cookie的方法如下,点击Head,点击加号,然后直接设置就可以了. C#中调用webService时插入Cookie 由于调用的时候必须要带上coo ...
- WCF入门教程1——WCF简要介绍
什么是WCF Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,可以翻译为Windows 通讯开发平台. 整合了原有的windo ...
- WCF系列教程之WCF服务宿主与WCF服务部署
本文参考自http://www.cnblogs.com/wangweimutou/p/4377062.html,纯属读书笔记,加深记忆. 一.简介 任何一个程序的运行都需要依赖一个确定的进程中,WCF ...
- WCF学习之旅—WCF寄宿前的准备(八)
一.WCF服务应用程序与WCF服务库 我们在平时开发的过程中常用的项目类型有“WCF 服务应用程序”和“WCF服务库”. WCF服务应用程序,是一个可以执行的程序,它有独立的进程,WCF服务类协定的定 ...
随机推荐
- HDU 1677 Nested Dolls
过了之后感觉曾经真的做过这样的类型的题. 之前一直非常疑惑二级排序的优先级问题,如今发现二级排序真的没有绝对的优先级. 对于此题,若按W排序,则有1到i件物品的W均小于等于第i+1件物品(设为A)的W ...
- NBA球员 ESPN前20排名:詹姆斯再居榜首
2014年 ESPN球员实力最后排名 没想到 保罗-乔治没有上榜.之前预測的火箭两大明星排名落后了,杜兰特排到第8有点出乎意料. 戴维斯升得那么快有点出乎意料,一个球队拥有两位排前十位的球队:骑士,快 ...
- AsyncTask測试多任务
本人进行过模拟測试,发现AsyncTask并不适合多任务,以及长期的异步任务,由于每次仅仅能执行一个AsyncTask,假设执行多个其他任务将会等待 以下通过一个代码样例和日志打印得到证实. 以下扩展 ...
- android 如何将电话簿SDN数字和其他普通的数字混合在一起?
最初的设计将默认SDN单独分出来,副标题"SDN". 下面的变化可以通过例如实现SDN并安排普通相同数量在一起,按字母顺序排列. DefaultContactListAdapter ...
- 蓝牙4.0BLE cc2540 cc2541 ios OAD课程(空中固件升级)[原版的,多图]
蓝牙4.0BLE cc2540 cc2541 ios OAD课程(件) 为阿莫单片机论坛 www.AmoMcu.com 原创.仅仅公布于csdn博客, 如需转载,请注明出处,谢谢! ...
- Team Foundation Server 2015使用教程--读取器tfs组的checkin权限修改
- ipad pro注定是失败的!
ipad pro注定是失败的! 把一个玩具操作系统装在生产力工具上就能产生生产力了? so young so simple!
- android做设计的每一个屏幕尺寸和分辨率(一个)
一个.与分辨率无关 1.使用dp(dpi) Android密度不依赖像素(dp)指定屏幕尺寸,它同意不同的屏幕尺寸和像素密度类似设备通过缩放来达到同样的效果. (不解决不同屏幕尺寸的问题?) 2.的资 ...
- 微博API怎么爬取其它未授权用户的微博/怎么爬取指定用户公布的微博
获取某个用户最新发表的微博列表:http://open.weibo.com/wiki/2/statuses/user_timeline 原接口已经被封.很多人都在问怎么获取指定用户的微博,于是写这篇B ...
- 从头到尾彻底理解KMP(转)
引言 KMP原文最初写于2年多前的2011年12月,因当时初次接触KMP,思路混乱导致写也写得非常混乱,如此,留言也是骂声一片.所以一直想找机会重新写下KMP,但苦于一直以来对KMP的理解始终不够,故 ...