由客户端不视为相同类型的 Web 服务引发的自定义异常(使用共享程序集)
Posted
技术标签:
【中文标题】由客户端不视为相同类型的 Web 服务引发的自定义异常(使用共享程序集)【英文标题】:Custom Exception Thrown by a Web Service not seen as same type by the Client (using shared assemblies) 【发布时间】:2014-03-09 20:26:26 【问题描述】:我创建了一个自定义异常InvalidSessionException
。但是,当尝试捕获或评估引发的异常是否属于该类型时,它不起作用。这意味着 EX is
和 Catch Ex
,不要评估为 InvalidSessionException
try
acc = this.fda.GetAccountHeader(this.selectedTicket.AccountId);
catch (Exception ex)
if (ex is Enterprise.Data.InformationModel.CustomExceptions.InvalidSessionException)
this.lblError.Text = Resources.Resource.error_sessionedTimedOut;
this.MPError.Show();
return;
我也尝试过(结果没有任何差异)
catch (Enterprise.Data.InformationModel.CustomExceptions.InvalidSessionException ex)
this.lblError.Text = Resources.Resource.error_sessionedTimedOut;
this.MPError.Show();
return;
catch (Exception ex)
return;
据我所知,抛出的异常是正确的类型。
更多信息:
ex.GetType().FullName
= "System.ServiceModel.FaultException1[[System.ServiceModel.ExceptionDetail, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"
服务上启用了重用类型?
【问题讨论】:
调试器似乎显示它是一个InvalidSessionException
。还有什么让您认为它不被认可?
在评估 'Catch' 或 'Is' 时它永远不会命中代码
是的,来自网络服务
那么实际上您并没有捕获该异常,而是另一个具有相同命名空间和类名的异常(除非您将原始程序集部署到客户端并重用类型)。有关更多详细信息,请参阅this post。
@owengerig 我不认为很容易看出区别,只是尝试看看 ex.GetType().FullName 是什么。程序集是否在客户端共享并且您明确设置为使用它们?默认情况下,即使有对该 DLL 的引用,它也不会重用类型。
【参考方案1】:
信用到期的信用 此答案的百分之九九分归功于Adriano Repetti 在此页面上留下的评论。我刚刚自己测试了这个解决方案,因为我遇到了与上面问题中描述的完全相同的问题。
问题 参考“配置服务参考”模式窗口;仅仅因为您选择“在所有引用的程序集中重用类型”并不意味着它实际上会这样做——这似乎是一个惰性操作,基本上,如果自动生成代码发生匹配它。解决方案 因此,如果您真的勾选了您关心的内容,似乎可以保证使用它而不是 maybe。这是通过将单选按钮从“在所有引用的程序集中重用类型”更改为“在指定的引用的程序集中重用类型”(第二个单选按钮选项)来实现的。
我的支持意见 似乎这特别影响了 FaultExceptions,我不知道为什么,但确实如此。我的项目中的 FaultExceptions 是在服务引用的命名空间下生成的,而不是从引用的程序集中重新使用它们。 特别令人费解的是,在查看服务参考代码的Reference.cs时,专门描述了namspace。即便如此,直到我做了上面描述的事情,它才起作用。最后我只想指出,这是一个很好的“打破规范”或“不规范”的例子。
【讨论】:
【参考方案2】:我相信你需要使用强类型FaultException<T>
。比如……
免责声明:以下代码未经测试
服务器端
[ServiceContract]
public interface ISampleService
[OperationContract]
[FaultContractAttribute(typeof(InvalidSessionException)]
void SampleMethod();
void SampleMethod()
...
throw new FaultException<InvalidSessionException>();
客户端
...
try
_wcfChannel.SampleMethod();
catch (FaultException<InvalidSessionException> ex)
// take appropriate action
补充阅读
MSDN:FaultException remondo.net:Using WCF Typed Fault Exceptions(一个简单的例子) iDesign:WCF Fault Contract(示例代码) 代码项目:A Beginner's Tutorial for Understanding Exception Handling, FaultExceptions and FaultContracts in WCF【讨论】:
从设计的角度来看,我个人不喜欢将我的服务器端代码耦合到 WCF 的想法。我宁愿抛出一个 normal 异常,然后在它进入 WCF 通信通道之前将其转换为FaultException<T>
。不知道这将是多么容易/难实现。
这是我采用的最新方法,但它仍然没有在正确的 catch 语句中捕获它,它总是使用通用的方法,即。 catch (exception ex) 而不是 catch (FaultExceptionFaultContractAttribute
属性是否已分配给适当的服务器端方法? (3) 考虑构建一个小型演示应用程序来测试实现——这将消除“噪音”并使您的问题更容易解决。 (4) 我的记忆很模糊......但您可能必须通过服务器端配置启用自定义 WCF 异常 - 请查看 MSDN 文档。
如果在 catch 块内设置断点,然后在 Visual Studio 的 Watch 窗口中尝试以下操作会发生什么情况:ex as FaultException以上是关于由客户端不视为相同类型的 Web 服务引发的自定义异常(使用共享程序集)的主要内容,如果未能解决你的问题,请参考以下文章
Jersey REST 客户端 - 将自定义 MediaType 视为 MediaType.APPLICATION_JSON