WebService/WCF
(一)如何发布WebService呢?使网络中其它机器能使用我的WebService
我写了一个简单的WebService,在本机上测试没有问题。
但网络中其它机器访问我的WebService时,提示“该调用只能用于本地测试”
修改web.config配置文件
< webServices >
< protocols >
< add name = " HttpGet " />
< add name = " HttpPost " />
</ protocols >
</ webServices >
</ System.Web >
(二)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应用)
1. WebService Application(*.asmx) + .net 2.0 Client Proxy
可以看到 Login 方法里将登录的 userName 保存在 Session 里。在 GetUserName 方法返回 Session 中的数据。
view plaincopy to clipboardprint?
[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;
}
}
[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)
view plaincopy to clipboardprint?
CookieContainer cookieContainer = new CookieContainer();
CookieContainer cookieContainer = new CookieContainer();
而每次调用都必须添加这个cookieContainer的实例。
PS: .net 3.5里仍然可以使用.net 2.0生成客户端:Add Service Reference -> Advance -> Add Web Reference
添加完WebService Reference后客户端调用:
view plaincopy to clipboardprint?
using (var svc = new MyWebSvc.Service1())
{
svc.CookieContainer = cookieContainer;
svc.Login(textBox1.Text);
}
using (var svc = new MyWebSvc.Service1())
{
svc.CookieContainer = cookieContainer;
svc.Login(textBox1.Text);
}
再一次调用:
view plaincopy to clipboardprint?
using (var svc = new MyWebSvc.Service1())
{
svc.CookieContainer = cookieContainer;
label1.Text = svc.GetUserName();
}
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了。
view plaincopy to clipboardprint?
using (var svc = new MyWCFWebSvc.Service1SoapClient())
{
svc.Login(textBox1.Text);
}
using (var svc = new MyWCFWebSvc.Service1SoapClient())
{
svc.Login(textBox1.Text);
}
再次调用:
view plaincopy to clipboardprint?
using (var svc = new MyWCFWebSvc.Service1SoapClient())
{
label1.Text = svc.GetUserName();
}
using (var svc = new MyWCFWebSvc.Service1SoapClient())
{
label1.Text = svc.GetUserName();
}
3. WCF Service Application(*.svc) + .net 3.5 Client Proxy
WCF的ServiceContract
view plaincopy to clipboardprint?
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetUserName();
[OperationContract]
void Login(string user);
}
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetUserName();
[OperationContract]
void Login(string user);
}
Service的实现,类似上面的WebMethod
view plaincopy to clipboardprint?
[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;
}
}
[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的代码如下:
view plaincopy to clipboardprint?
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);
}
}
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);
}
}
出处:http://blog.csdn.net/fangxinggood/archive/2011/04/19/6332489.aspx
WebService/WCF相关推荐
- [转]VSTO+WinForm+WebService+WCF+WPF示例
看到一个不错的示例程序分享给大家,Vincent.Q的<VSTO+WinForm+WebService+WCF+WPF示例>很不错! 原文如下: 前段时间去图书馆借书,无意中发现这样 ...
- [转自雨痕]RESTful WCF
原文:http://www.rainsts.net/article.asp?id=651 REST 最近很热门-- WCF 3.5 增加了对 REST 的支持 -- System.ServiceMod ...
- Windows phone 应用开发[2]-数据缓存
今天把JDi/Server测试做完.终于有了时间来写写关于这个项目总结.关于我在博客上Post这些文章内容都是从实际项目应用而来.当然有些问题解决方案也是不断被重复设计修改.期间也碰到诸多问题.也曾为 ...
- MVC+EF三层+抽象工厂
MVC+EF三层+抽象工厂项目搭建 注意:项目经过两次搭建,所以截图中顶级命名空间有ZHH和ZHH2区别,但是架构的内容是一样的,可以将ZHH和ZHH2视为同一命名空间 一:权限管理 二:搜索 |-L ...
- MVC+EF三层+抽象工厂项目搭建
注意:项目经过两次搭建,所以截图中顶级命名空间有ZHH和ZHH2区别,但是架构的内容是一样的,可以将ZHH和ZHH2视为同一命名空间 一:权限管理 二:搜索 |-Lucene.net(速度快)+盘古分 ...
- 在鹅厂面试5轮后扑街!微服务架构,我拿什么拯救你!
上周五接到朋友的电话,此前他一路披荆斩棘,离鹅厂Offer大概仅一步之遥.电话一接通我就说了一通让他请客吃饭的话,对面沉默了几秒钟,淡淡地说了句 "我终面没过...." 这让我一时 ...
- 2020年,我来盘点下微服务架构技术栈
2020年了,很多小伙伴儿对微服务还比较陌生,说起来很多人可能不敢相信,其实微服务这个概念早在2012年就提出来了,经过了这些年的发展,现在已经成为企业非常主流的架构选项了.今天,我就来带大家一起探讨 ...
- 插件式架构设计实践:插件式系统架构设计简介
本系列博文将使用微软RIA技术解决方案Silverlight以及扩展性管理框架Managed Extensibility Framework(MEF),以插件式架构设计为导线,分享本人在从事基于微软S ...
- 在php中调用java接口吗,php 调用 java 接口
php 需要开启 curl模块 /* * HTTP 请求函数封装 */ function http_request_cloudzone($url, $data){ //var_dump($url.&q ...
最新文章
- python与Redis数据库进行交互(安装包、调用模块、StrictRedis对象⽅法、交互代码示例(string增加、string获取、string修改、string删除、获取键))
- Go语言学习之旅01--变量与数据
- 40亿次仿真学习:人工智能5:0大胜人类飞行员
- 斯坦福CS231n项目实战(四):浅层神经网络
- vue实现两个数组的合并
- php与硬件通过wifi对接,基于ESP8266的WiFi排插接入贝壳互联实现天猫精灵控制
- 未能加载文件或程序集“Oracle.DataAccess”或它的某一个依赖项。试图加载格式不正确的程序。...
- linux中断响应时间太慢_Linux中的进程调度有哪些核心概念?
- 基于机器视觉的滑块检测
- 他山之石 可以攻玉-《海量数据库解决方案》
- 【完美解决方案】Error during artifact deployment. See server log for details.
- 四大主流新闻App竞品分析
- Vue实现图形化积木式编程(十二)
- 便利贴--9{Cesium+js绘制多个点和多个线的图层,加标题}
- python列表生成式
- 好用的Mac视频下载软件--Downie 4
- MySQL——连接查询
- 数字北京城,航行在联通2000M的“大运河”
- 网络爬虫学习第二弹:requests库的使用
- 吴思里:PCG腾讯文档前端面试经历