[WCF]缺少一行代码引发的血案
这是今天作项目支持的发现的一个关于WCF的问题,虽然最终我只是添加了一行代码就解决了这个问题,但是整个纠错过程是痛苦的,甚至最终发现这个问题都具有偶然性。具体来说,这是一个关于如何自动为服务接口(契约)的每个操作添加FaultContract与WCF服务元数据发布的问题。接下来通过一个简单的实例来说明这个因为少写了一行代码引发的血案。 一、手工添加FaultContractWCF采用基于消息的通信方式,Endpoint的ABC三要素之一的契约(Contract)的本质就是定义消息的结构。契约不仅定义了正常请求和响应负载的结构,还定义了承载异常信息的响应消息的结构。为了让契约能够响应消息承载的错误信息,承载错误信息的类型需要利用FaultContractAttribute特性注册到服务接口的操作方法上。 1: [ServiceContract]
2: public interface IMyService 3: {
4: [OperationContract]
5: [FaultContract(typeof(ServiceExceptionInfo))] 6: string GetData(int value); 7: }
8:?
9: class MyService : IMyService 10: {
11: value) 12: {
13: var ex = new InvalidOperationException("Invalid operation..."); 14: throw new FaultException<ServiceExceptionInfo>(new ServiceExceptionInfo(ex)); 15: }
16: }
17:?
18: [DataContract]
19: class ServiceExceptionInfo 20: {
21: [DataMember]
22: string ExceptionType { get; set; } 23:?
24: [DataMember]
25: string Message { get; set; } 26: public ServiceExceptionInfo(Exception ex) 27: {
28: this.ExceptionType = ex.GetType().AssemblyQualifiedName; 29: this.Message = ex.Message; 30: }
31: }
如下面的代码片段所示,由于GetData操作抛出的FaultException对象采用一个ServiceExceptionInfo来描述详细错误信息,所以我们在定义服务接口的时候需要利用FaultContractAttribute将ServiceExceptionInfo这个类型注册到GetData方法上。 二、利用自定义ServiceHost自动注册ServiceExceptionInfo类型如果多个操作都需要注册这么一个ServiceExceptionInfo类型,这其实是一件很繁琐的事情。对于今天找我们作技术支持的那个项目来说,由于采用了我们提供的一个自动化异常处理框架,要求所有的操作都需要注册一个类似于ServiceExceptionInfo的类型来描述最终的错误消息。为了让具体的项目可以不用在每个操作上都添加一个FaultContractAttribute,我们自定义了一个ServiceHost来实现了对它的自动注册。如下所示的MyServiceHost模拟了FaultContract自动化注册的逻辑。 2: {
4: { } protected override void OnOpening() 8: base.OnOpening();
10: { ); 13: { 15: { 17: fault.DetailType = typeof(ServiceExceptionInfo);
19: } 21: } 23: } 25: class MyServiceHostFactory : ServiceHostFactory
27: override ServiceHost CreateServiceHost(Type serviceType,Uri[] baseAddresses)
return new MyServiceHost(serviceType,baseAddresses);
<system.serviceModel> 6: serviceDebug includeExceptionDetailInFaults 7: </ 8: 9: 10: servicesservice name="WcfService.MyService" 12: endpoint binding="basicHttpBinding" contract="WcfService.IMyService" 13: service 14: 15: serviceHostingEnvironment 16: serviceActivations 17: add ="WcfService.MyService" relativeAddress="myservice.svc" factory="WcfService.MyServiceHostFactory" 18: 19: serviceHostingEnvironment> 17: fault.Name = "ServiceExceptionInfoFault";
20: } 22: } 24: } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 具有多个身份验证过滤器的ASP.net Web API 2控制器
- asp.net-mvc – “信号量超时期限已过期”SQL Azure
- asp.net – 如何让网站支持Windows Live Writer?
- asp.net – 使用字符串列表绑定GridView
- ASP.NET Core在Azure Kubernetes Service中的部署和管理
- 如何在ASP.NET MVC模型中为POST保存选定的DropDownList值?
- asp.net-mvc – 在MVC中检查图像mime,大小等
- asp.net-mvc – ASP.NET MVC – RequireJS最佳的多页面应用
- asp.net-mvc – Automapper映射到嵌套类
- asp.net-mvc – Kendo UI Grid – 显示行号
- ASP.NET捆绑和分类 – 包括用于生产捆绑包和未压
- 启动ASP.NET窗体身份验证
- asp.net – 你如何’规范’一个Web服务器来支持给
- asp.net – 如何保护我的通用处理程序调用?
- asp.net-mvc – Asp.net MVC TextArea
- asp.net-mvc – 什么是ASP.NET MVC的验证选项
- asp.net核心 – 在Visual Sudio 2015中的Aurelia
- asp.net-mvc – 仍然支持MetaWeblog API吗?
- asp.net-mvc – 如何告诉Resharper查看部分视图的
- asp.net – 错误:“无法读取配置部分’system.w