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服务类协定的定 ...
随机推荐
- 【浅墨著作】《OpenCV3编程入门》内容简单介绍&勘误&配套源码下载
经过近一年的沉淀和总结,<OpenCV3编程入门>一书最终和大家见面了. 近期有为数不少的小伙伴们发邮件给浅墨建议最好在博客里面贴出这本书的文件夹,方便大家更好的了解这本书的内容.事实上近 ...
- Paypal-Express Checkout快捷支付方式的android端开发心得(二)
一.前导 上一篇讲的不是非常好,这里再又一次讲一下. Paypal手机支付有2种形式: 1.Mobile Express Checkout,MEC,快捷支付 2.MPL 假设採用MEC支付方式,这样的 ...
- JS基础——函数的创建和使用
在JS中函数在使用时实质上和我们平时学习的编程语言中的函数类似,它相同也具有函数名,參数,返回值,函数体等这些寻常函数所具有的内容.可是作为一种脚本语言,它确实也有自己不一样的地方. 一.创建 < ...
- STL中间set具体用法!!!!
1.关于set C++ STL 之所以得到广泛的赞誉,也被非常多人使用.不仅仅是提供了像vector, string, list等方便的容器,更重要的是STL封装了很多复杂的数据结构算法和大量经常使用 ...
- 修饰模式(Decorator结构化)C#简单的例子
修饰模式(Decorator结构化)C#简单的例子 播放器的基本功能是移动.执行等.BaseAbility 新增功能:1.伤害技能harmAbility:2.阻碍技能BaulkAbility:3.辅助 ...
- 为大型数据文件每行只能产生id
为大型数据文件每行只能产生id 4个主要思路: 1 单线程处理 2 普通多线程 3 hive 4 Hadoop 搜到一些參考资料 <Hadoop实战>的笔记-2.Hadoop输入与输出 h ...
- SQL Server 优化存储过程的七种方法
原文:SQL Server 优化存储过程的七种方法 优化存储过程有很多种方法,下面介绍最常用的7种. 1.使用SET NOCOUNT ON选项 我们使用SELECT语句时,除了返回对应的结果集外,还会 ...
- hdu3836联通的强还原性点
Equivalent Sets Time Limit: 12000/4000 MS (Java/Others) Memory Limit: 104857/104857 K (Java/Other ...
- C#中实现并发
C#中实现并发的几种方法的性能测试 0x00 起因 去年写的一个程序因为需要在局域网发送消息支持一些命令和简单数据的传输,所以写了一个C/S的通信模块.当时的做法很简单,服务端等待链接,有用户接入后开 ...
- 设计模式 - 迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释
迭代模式(iterator pattern) Java 迭代器(Iterator) 详细解释 本文地址: http://blog.csdn.net/caroline_wendy 參考迭代器模式(ite ...