WCF - DataContract 继承
发布日期:2021-06-29 03:54:10
浏览次数:2
分类:技术文章
本文共 5971 字,大约阅读时间需要 19 分钟。
DataContract 支持继承方式,但和我们前面所提到的 ServiceContract 一样,有点小小的问题。看下面的例子。
(为显示方便,以下代码有删减。) [DataContract] public class Data { [DataMember] public int X; } [DataContract] public class Data2 : Data { [DataMember] public int Y; } [ServiceContract] public interface IMyService { [OperationContract] void Test(Data d); }
客户端代理 //------------------------------------------------------------------------------ // <auto-generated> // 此代码由工具生成。 // 运行库版本:2.0.50727.42 // // 对此文件的更改可能会导致不正确的行为,并且如果 // 重新生成代码,这些更改将会丢失。 // </auto-generated> //------------------------------------------------------------------------------ namespace ConsoleApplication1.localhost { [GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")] [DataContractAttribute(Namespace = "...")] [SerializableAttribute()] public partial class Data : object, IExtensibleDataObject { } }
从 客户端生成的代码来看,我们显然不能使用 Data2。怎样才能使用 Data2 呢?将契约 IMyService 的 Test 方法参数改成 "Data2 d"?当然不行,这样一来 Data 就不能用了,更不要说什么多态了。这时候就要使用另外一个特性 —— ServiceKnownTypeAttribute。继续看我们修改后的代码。 [DataContract] public class Data { [DataMember] public int X; } [DataContract] public class Data2 : Data { [DataMember] public int Y; } [ServiceContract] [ServiceKnownType(typeof(Data2))] public interface IMyService { [OperationContract] void Test(Data d); }
客户端代理 //------------------------------------------------------------------------------ // <auto-generated> // 此代码由工具生成。 // 运行库版本:2.0.50727.42 // // 对此文件的更改可能会导致不正确的行为,并且如果 // 重新生成代码,这些更改将会丢失。 // </auto-generated> //------------------------------------------------------------------------------ namespace ConsoleApplication1.localhost { [GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")] [DataContractAttribute(Namespace = "...")] [SerializableAttribute()] [KnownTypeAttribute(typeof(Data2))] public partial class Data : object, IExtensibleDataObject { } [GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")] [DataContractAttribute(Namespace = "...")] [SerializableAttribute()] public partial class Data2 : Data { } }
非常好,Data2 出现了,而且它也继承自 Data,我们写个完整的例子,看看是否是我们所设想的多态。服务器端代码 [DataContract] public class Data { [DataMember] public int X; } [DataContract] public class Data2 : Data { [DataMember] public int Y; } [ServiceContract] [ServiceKnownType(typeof(Data2))] public interface IMyService { [OperationContract] void Test(Data d); } public class MyServie : IMyService { public void Test(Data d) { Console.WriteLine(d.GetType()); Console.WriteLine(d.X); Console.WriteLine((d as Data2).Y); } }
客户端代码 using (MyServiceClient client = new MyServiceClient()) { Data2 d = new Data2(); d.X = 1234; d.Y = 5678; client.Test(d); }
执行后服务器端输出:Data212345678ServiceKnownTypeAttribute 还可以直接用在 Method 上,另外还要注意我们将 ServiceKnownTypeAttribute 放在服务契约上,而不是其他什么地方。 [AttributeUsage(AttributeTargets.Interface| AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)] public sealed class ServiceKnownTypeAttribute : Attribute { }
相应地,我们还可以直接在配置文件中添加 ServiceKnownTypeAttribute,这样可以避免修改服务器端代码(也许吧?前提是 Data2 要放到另外一个程序集中)。看另外一种情形。 public interface IData { int X { get; set; } } [DataContract] public class Data : IData { private int x; [DataMember] public int X { get { return x; } set { x = value; } } } [ServiceContract] public interface IMyService { [OperationContract] void Test(IData d); }
麻烦依旧,看看自动生成的客户端代理。 //------------------------------------------------------------------------------ // <auto-generated> // 此代码由工具生成。 // 运行库版本:2.0.50727.42 // // 对此文件的更改可能会导致不正确的行为,并且如果 // 重新生成代码,这些更改将会丢失。 // </auto-generated> //------------------------------------------------------------------------------ namespace ConsoleApplication1.localhost { [GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] [ServiceContractAttribute(ConfigurationName = "ConsoleApplication1.localhost.IMyService")] public interface IMyService { [OperationContractAttribute(Action = "http://tempuri.org/IMyService/Test", ReplyAction = "...")] void Test(object d); } [GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] public interface IMyServiceChannel : IMyService, IClientChannel { } [DebuggerStepThroughAttribute()] [GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] public partial class MyServiceClient : ClientBase<IMyService>, IMyService { public void Test(object d) { base.Channel.Test(d); } } }
没有 IData,没有 Data,取而代之的是 object。这意味着很大的麻烦,不是吗?还是让 ServiceKnownTypeAttribute 出来吧。 [ServiceContract] public interface IMyService { [OperationContract] [ServiceKnownType(typeof(Data))] void Test(IData d); }
更 新后的客户端代理虽然出现了 Data,但 IData 依然不见踪影,Test 方法参数依然是 "object d"。查阅了 MSDN 的一些说明,原因可能是 "the interface itself will not be included in the exported metadata"。不过这并不妨碍我们调用服务,看来 DataContract 不支持 Interface 也是有些原因的。 //------------------------------------------------------------------------------ // <auto-generated> // 此代码由工具生成。 // 运行库版本:2.0.50727.42 // // 对此文件的更改可能会导致不正确的行为,并且如果 // 重新生成代码,这些更改将会丢失。 // </auto-generated> //------------------------------------------------------------------------------ namespace ConsoleApplication1.localhost { [GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")] [DataContractAttribute(Namespace = "...")] [SerializableAttribute()] public partial class Data : object, IExtensibleDataObject { } [GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] [ServiceContractAttribute(ConfigurationName = "ConsoleApplication1.localhost.IMyService")] public interface IMyService { [OperationContractAttribute(Action = "http://tempuri.org/IMyService/Test", ReplyAction = "...")] [System.ServiceModel.ServiceKnownTypeAttribute(typeof(ConsoleApplication1.localhost.Data))] void Test(object d); } [GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] public interface IMyServiceChannel : IMyService, IClientChannel { } [DebuggerStepThroughAttribute()] [GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")] public partial class MyServiceClient : ClientBase<IMyService>, IMyService { public void Test(object d) { base.Channel.Test(d); } } }
转载地址:https://blog.csdn.net/zengjibing/article/details/3812388 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!
发表评论
最新留言
哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年04月02日 06时01分07秒
关于作者
喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
TensorFlow实现:卷积神经网络识别手势动作(有代码与演示)
2021-07-02
win10删除文件夹需要提供管理员权限(实测可用超简单方法)
2021-07-02
《面向通用人工智能的混合天机芯片架构》论文简单小结
2021-07-02
深度学习的几种权重初始化
2021-07-02
ResNet残差网络学习小结
2021-07-02
蓝桥1
2021-07-02
样题2
2019-04-29
煤球数目
2019-04-29
购物单
2019-04-29
等差素数列
2019-04-29
承压计算
2019-04-29
方格分割(DFS)
2019-04-29
取位数
2019-04-29
最大公共子串
2019-04-29
日期问题
2019-04-29
全国大学生英语竞赛C类
2019-04-29
Flink1.7.2 sql 批处理示例
2019-04-29
直播间搭建需要避免的三点要素,开发直播app软件并不简单 ...
2019-04-29
使用 Phan 为你的 PHP 项目保驾护航 - 代码静态扫描 ...
2019-04-29
你与一份好简历之间的距离
2019-04-29