C#:无法在WCF客户端中正常使用泛型ResponseModel类
解决WCF客户端无法直接使用泛型ResponseModel的问题
首先得说,你遇到的这个带随机后缀的类(比如ResponseModelOfArrayOfstringuHEDJ7Dj),是因为你用了Web引用这种旧的ASMX风格的引用方式——它对WCF的泛型支持很差,会把泛型类型直接展开成具体的非泛型类,还自动加了一堆乱码后缀。要想用ResponseModel<string>这种原生泛型写法,咱们可以按下面的方法来解决:
方法1:改用WCF官方推荐的「服务引用」(最推荐)
Web引用是为旧ASMX服务设计的,对WCF的特性支持不足,换成服务引用就能完美解决泛型问题:
- 右键你的客户端项目 → 选择「添加」→「服务引用」
- 在弹出的窗口里,输入你的WCF服务地址,点击「前往」找到服务端点
- 点击窗口左下角的「高级」按钮,在弹出的「服务引用设置」里:
- 如果你的客户端项目可以直接引用包含
ResponseModel<T>的服务端类库,记得勾选「重用引用的程序集中的类型」,这样客户端会直接复用原有的泛型类,不用重新生成 - 如果不能引用类库,也没关系,只要服务端的元数据配置正确,服务引用工具会自动生成
ResponseModel<T>泛型类
- 如果你的客户端项目可以直接引用包含
- 完成添加后,你就能直接像这样实例化泛型类了:
ManagementAgentServices.ResponseModel<string> Response = new ManagementAgentServices.ResponseModel<string>();
方法2:给服务端的泛型类添加数据契约标记(辅助步骤)
有时候服务端的泛型类没有正确标记数据契约,会导致元数据无法正确暴露泛型定义,客户端也就生成不了泛型类。给你的ResponseModel<T>加上[DataContract]和[DataMember]标记:
[DataContract] public class ResponseModel<T> { [DataMember] public string DeveloperMessage { get; set; } [DataMember] public string Message { get; set; } [DataMember] public string Status { get; set; } [DataMember] public TimeSpan RequestTime { get; set; } [DataMember] public virtual T RetrievedData { get; set; } }
同时确保服务端的Web.config里开启了元数据发布:
<system.serviceModel> <services> <service name="YourServiceName"> <endpoint address="" binding="basicHttpBinding" contract="YourContractName"/> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior> <serviceMetadata httpGetEnabled="true"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
方法3:手动修改Web引用生成的代码(临时方案,不推荐)
如果因为项目限制必须用Web引用,你可以手动修改自动生成的Reference.cs文件:
- 找到所有类似
ResponseModelOfArrayOfstringuHEDJ7Dj的类,把它们重构为一个泛型类ResponseModel<T> - 替换所有具体类型的使用场景为泛型写法
- 注意:每次更新Web引用都会覆盖这个修改,所以这只是临时应急的办法,长期来看还是建议换成服务引用
内容的提问来源于stack exchange,提问作者Zame
相关产品推荐
相关产品推荐

