关于已部署的WCF服务升级的问题
在日常的开发过程中,我们会经常迭代发布不同的版本,所以WCF服务的接口也会经常处于变动的状态,比如在传递实体类中新加一个字段、修改参数名称等等关于服务升级的问题。但是我们不可能让已发布的版本重新引用新的服务,这是不现实的,所以我们在升级WCF服务时,一定要让服务兼容以前的版本。现在我们分别介绍关于服务升级的几个常用情况。
一、参数变动
我们来实现最初的版本1.0,新建一个服务接口,服务实现很简单,在Output窗口中简单输出服务接收到的参数值。
[ServiceContract]
public interface ITestingService
{
[OperationContract]
void AddUser(string id, string username, int age);
}
public class TestingService : ITestingService
{
public void AddUser(string id, string username, int age)
{
System.Diagnostics.Debug.WriteLine(string.Format("id = {0}", id)); System.Diagnostics.Debug.WriteLine(string.Format("username = {0}", username)); System.Diagnostics.Debug.WriteLine(string.Format("age = {0}", age));
}
}
在客户端引用1.0版本的服务,调用服务接口
class Program
{
static void Main(string[] args)
{
var testingServiceClient = new TestingServiceClient(); testingServiceClient.AddUser("", "James", ); Console.ReadKey();
}
}
在服务端的Output输出结果如下

1.添加参数
考虑一种特别常用的情形,我需要添加一个新的字段,以便得到更多的信息,我们需要升级服务至2.0,所以我们需要修改接口和实现。最终的结果当然是不影响引用1.0服务的客户端的继续使用。
让我们修改接口和实现。
[ServiceContract]
public interface ITestingService
{
[OperationContract]
void AddUser(string id, string username, int age, string city);
}
public class TestingService : ITestingService
{
public void AddUser(string id, string username, int age, string city)
{
System.Diagnostics.Debug.WriteLine(string.Format("id = {0}", id)); System.Diagnostics.Debug.WriteLine(string.Format("username = {0}", username)); System.Diagnostics.Debug.WriteLine(string.Format("age = {0}", age)); System.Diagnostics.Debug.WriteLine(string.Format("city = {0}", city));
}
}
首先我们需要保证引用1.0服务的客户端的继续使用,所以我们先测试引用1.0服务的客户端。

从测试结果可以看到,在引用旧的服务的客户端在调用新的服务时,可以正常调用,只是新添加的字段是默认值。这是正确的结果,因为在旧的客户端传递过来的数据中不包含新添加的字段的信息,自然新添加的字段的值是默认的值。
2.删除不再需要的参数
紧接1.0版本,假设在新的2.0版本中不再需要age的值,所以需要在接口中删除这个参数,所以需要修改接口和实现。
[ServiceContract]
public interface ITestingService
{
[OperationContract]
void AddUser(string id, string username);
}
public class TestingService : ITestingService
{
public void AddUser(string id, string username)
{
System.Diagnostics.Debug.WriteLine(string.Format("id = {0}", id)); System.Diagnostics.Debug.WriteLine(string.Format("username = {0}", username));
}
}
首先我们需要保证引用1.0服务的客户端的继续使用,所以我们先测试引用1.0服务的客户端。

从测试结果可以看到,在引用旧的服务的客户端在调用新的服务时,可以正常调用。
3.修改参数名(重构)
紧接1.0版本,假设在新的2.0版本中需要修改username名为name,所以需要修改接口和实现。
[ServiceContract]
public interface ITestingService
{
[OperationContract]
void AddUser(string id, string name);
}
public class TestingService : ITestingService
{
public void AddUser(string id, string name)
{
System.Diagnostics.Debug.WriteLine(string.Format("id = {0}", id)); System.Diagnostics.Debug.WriteLine(string.Format("username = {0}", name));
}
}
在保证客户端不引用新的服务的前提下,我们测试客户端的服务调用情况。

从结果可以看到,如果修改了参数的名称则会影响到旧版本客户端的使用,难道没有别的什么方法可以解决这个问题么?答案是有的,如果想要重构但是不想改动客户端代码的话,那么可以给参数加上一个MessageParameter的属性,代码如下:
[ServiceContract]
public interface ITestingService
{
[OperationContract]
void AddUser(string id, [MessageParameter(Name = "username")]string name);
}
重新测试旧版本的客户端,可以看到最终的结果又恢复正常。

二、实体的变动
在第一部分我们谈论的是参数的变动,在第二部分我们变化实体中属性的变动。先来定义最初的1.0服务版本。
[DataContract]
public class User
{
[DataMember]
public string Id
{
get;
set;
} [DataMember]
public string Name
{
get;
set;
} [DataMember]
public int Age
{
get;
set;
} }
[ServiceContract]
public interface ITestingService
{
[OperationContract]
void AddUser(User user);
}
public class TestingService : ITestingService
{
public void AddUser(User user)
{
System.Diagnostics.Debug.WriteLine(string.Format("id = {0}", user.Id)); System.Diagnostics.Debug.WriteLine(string.Format("username = {0}", user.Name)); System.Diagnostics.Debug.WriteLine(string.Format("age = {0}", user.Age));
}
}
客户端引用最初的服务
class Program
{
static void Main(string[] args)
{
var testingServiceClient = new TestingServiceClient(); var user = new User() { Id = "", Name = "Tommy", Age = }; testingServiceClient.AddUser(user); Console.ReadKey();
}
}
测试结果如下

1.在实体类中添加属性
在User类中添加City属性,以便在新的服务版本中获取更多的用户信息。服务接口不变,只需修改实体类和服务实现。
[DataContract]
public class User
{
[DataMember]
public string Id { get; set; } [DataMember]
public string Name { get; set; } [DataMember]
public int Age { get; set; } [DataMember]
public string City { get; set; } }
public void AddUser(User user)
{
System.Diagnostics.Debug.WriteLine(string.Format("id = {0}", user.Id)); System.Diagnostics.Debug.WriteLine(string.Format("username = {0}", user.Name)); System.Diagnostics.Debug.WriteLine(string.Format("age = {0}", user.Age)); System.Diagnostics.Debug.WriteLine(string.Format("city = {0}", user.City));
}
在保证客户端不引用新的服务的前提下,测试客户端的服务调用情况。从结果可以看出,旧的客户端可以正常调用新的服务,只是新添加的字段没有显式赋值。

2.在实体类中删除属性
在User类中删除Age属性。服务接口不变,只需修改实体类和服务实现。
[DataContract]
public class User
{
[DataMember]
public string Id { get; set; } [DataMember]
public string Name { get; set; } }
public class TestingService : ITestingService
{
public void AddUser(User user)
{
System.Diagnostics.Debug.WriteLine(string.Format("id = {0}", user.Id)); System.Diagnostics.Debug.WriteLine(string.Format("username = {0}", user.Name)); }
}
在保证客户端不引用新的服务的前提下,测试客户端的服务调用情况。从结果可以看出,旧的客户端可以正常调用新的服务。

3.在实体类中修改属性名
在User类中修改Name属性的名称为UserName。服务接口不变,只需修改实体类和服务实现。
[DataContract]
public class User
{
[DataMember]
public string Id { get; set; } [DataMember]
public string UserName { get; set; } [DataMember]
public int Age { get; set; } }
public class TestingService : ITestingService
{
public void AddUser(User user)
{
System.Diagnostics.Debug.WriteLine(string.Format("id = {0}", user.Id)); System.Diagnostics.Debug.WriteLine(string.Format("username = {0}", user.UserName)); }
}
在保证客户端不引用新的服务的前提下,测试客户端的服务调用情况。

从结果可以看到,如果修改了实体属性的名称则会影响到旧版本客户端的使用,可以在DataMemeber中设定Name属性的值,代码如下
[DataMember(Name = "Name")]
public string UserName { get; set; }
重新测试客户端,发现可以继续正常使用。

关于已部署的WCF服务升级的问题的更多相关文章
- WCF服务部署到IIS上,然后通过web服务引用方式出现错误的解决办法
本文转载:http://www.cnblogs.com/shenba/archive/2012/01/06/2313932.html 昨天在用IIS部署一个WCF服务时,碰到了如下错误: 理解了文档内 ...
- WCF服务端与客户端时间匹配问题
当服务端部署的WCF服务服务在被客户机调用时,如果显示: 错误,展开后,详细错误为:An error occurred when verifying security for the message ...
- 关于WCF服务 http://XXXXXX/XXX/xxx.svc不支持内容类型 application/sop+xml;charset=utf-8 错误解决方法
有时候用IIS部署一个WCF服务时,无论是在客户端还是在服务端通过地址都能正常访问. 但是当你在客户端添加服务引用时, 怎么也添加不上, 会碰到了如下错误: 好啦. 现在说说怎么解决吧. 其实很简单. ...
- WCF学习之旅—WCF服务部署到应用程序(十)
上接 WCF学习之旅—WCF寄宿前的准备(八) WCF学习之旅—WCF服务部署到IIS7.5(九) 五.控制台应用程序宿主 (1) 在解决方案下新建控制台输出项目 ConsoleHosting.如下 ...
- Wcf for wp8 使用iis Express 承载Wcf服务部署发布网站(三)
我们接下来要做的是 本地电脑当作服务器(模拟外网服务器)来承载Wcf服务程序,通过引用本地电脑ip地址访问wcf服务程序接口 http://192.168.1.123/Service1.svc 一.先 ...
- WCF系列教程之WCF服务宿主与WCF服务部署
本文参考自http://www.cnblogs.com/wangweimutou/p/4377062.html,纯属读书笔记,加深记忆. 一.简介 任何一个程序的运行都需要依赖一个确定的进程中,WCF ...
- .Net WCF服务部署IIS详细解析
官方解析:Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,可以翻译为Windows 通讯开发平台.整合了原有的windows通 ...
- WCF学习之旅—WCF服务部署到IIS7.5(九)
上接 WCF学习之旅—WCF寄宿前的准备(八) 四.WCF服务部署到IIS7.5 我们把WCF寄宿在IIS之上,在IIS中宿主一个服务的主要优点是在发生客户端请求时宿主进程会被自动启动,并且你可以 ...
- WCF服务部署IIS
一.将WCF服务部署到IIS上 [转载自简单笑容——http://www.cnblogs.com/skdsxx/p/5072726.html ] 1.首先检测电脑上是否安装了IIS,一般来说Win7 ...
随机推荐
- 最新Altium_Designer_Beta_18.7.is AD18安装教程及破解说明
下解Altium_Designer带破解的压缩包. 下载链接:https://pan.baidu.com/s/1TlPHtSthJKxLcXWcCR-q-g 密码:bt0g 解压缩Altium_Des ...
- uCrop 源码剖析
GitHub: uCrop, 版本为 2.2.2 主要是探究一下内部对于图片按比例的裁剪以及压缩, 应该会更很长一段时间 疑惑点 这里记下一些源码分析过程中遇到的疑惑点 sample/src/main ...
- PIE currently adds full or partial support to IE 6 through 8 for the following CSS3 features
PIE stands for Progressive Internet Explorer. It is an IE attached behavior which, when applied to a ...
- P2351 [SDOi2012]吊灯
P2351 [SDOi2012]吊灯 https://www.luogu.org/problemnew/show/P2351 题意: 一棵树,能否全部分成大小为x的联通块. 分析: 显然x是n ...
- jmeter "you cannot switch bacause data cannot be converted to target Tab data,empty data to switch"报错
jmeter "you cannot switch bacause data cannot be converted to target Tab data,empty data to swi ...
- Python列表的深拷贝和浅拷贝
1. Python列表的拷贝 对于python里面如果想要进行列表的拷贝和复制,具体的操作语句如下: 1) 深拷贝: M=[A,b,a,c] N=M[:] 2) 浅拷贝: N=M 有人说可以直接将M赋 ...
- php导出excel表格的使用
网站后台有很多列表数据,常常都会有导出excel表格的需求,和大家分享一个实用的导出excel表格方法: 不多说,上代码: /** * @param array $data 要导出的数据 * @par ...
- [JSON].typeOf( keyPath )
语法:[JSON].typeOf( keyPath ) 返回:[String | Number | Boolean | Json | Array | Function | 空字符] 说明:获取指定键 ...
- 拥抱移动端,jQueryui触控设备兼容插件
http://touchpunch.furf.com/ ps:要FQ. jQuery UI Touch Punch Touch Event Support for jQuery UI Tested o ...
- Docker Remote API v1.24
1. Brief introduction The Remote API has replaced rcli. The daemon listens on unix:///var/run/docker ...