简体   繁体   English

WCF FaultException <SqlException> 被捕获为CommunicationException

[英]WCF FaultException<SqlException> caught as CommunicationException

I have a WCF service where I am catching an SqlException and then returning it as a FaultException like this 我有一个WCF服务,我在其中捕获SqlException ,然后将其作为FaultException像这样返回

throw new FaultException<SqlException>(...);

And on the client side, I am catching it like this 在客户端,我正在这样捕捉它

catch (FaultException<SqlException> e)
{
    // do something with exception
}
catch (FaultException<Exception> e)
{
    // do something with exception
}

I don't believe I have a problem in my web.config on the service side or the app.config on the client side (a winform client) as I am able to catch FaultException<ArgumentException> , FaultException<Exception> , etc. but not FaultException<SqlException> 我不认为服务端的web.config或客户端(winform客户端)的app.config出现问题,因为我能够捕获FaultException<ArgumentException>FaultException<Exception>等。但不是FaultException<SqlException>

I have not found anything indicating that I can't pass SqlExceptions down to the client, my operation contract is properly configured with things like [FaultContract(typeof(SqlException))] , and [FaultContract(typeof(Exception))] 我没有发现任何指示不能将SqlExceptions传递给客户端的信息,我的操作合同已正确配置,例如[FaultContract(typeof(SqlException))][FaultContract(typeof(Exception))]

Anyone seen this or know for a fact that I can't (or maybe need to do something special to) pass faults of type SqlException down to the client? 任何人都看过这个或者知道我不能(或者可能需要做一些特殊的事情)将SqlException类型的错误传递给客户端的事实吗? Thank you. 谢谢。

throw new FaultException<Exception> is not really how the WCF fault system is intended to be used. throw new FaultException<Exception>并不是真正打算使用WCF故障系统。 The type you specify is serialized across the wire in the <Detail> element of a SOAP fault. 您指定的类型在SOAP故障的<Detail>元素中通过电线进行了序列化。 Normally, this type is a WCF data contract class that you write, eg 通常,此类型是您编写的WCF数据协定类,例如

[DataContract]
public class MyFault {
    [DataMember]
    public string Message {get; set;}
}

throw new FaultException<Exception> happens to work because Exception is [Serializable] , and the DataContractSerializer is capable of handling [Serializable] types as well as [DataContract] types. throw new FaultException<Exception>可以正常工作,因为Exception[Serializable] ,并且DataContractSerializer能够处理[Serializable]类型以及[DataContract]类型。

However, there are serious limitations to this approach. 但是,这种方法存在严重的局限性。 The DataContractSerializer does not handle [Serializable] types very well. DataContractSerializer不能很好地处理[Serializable]类型。 Only fields of primitive types ( string , int , etc) will be transmitted correctly. 仅原始类型的字段( stringint等)将被正确传输。 That is just about OK for a very simple exception type, but for a complex type like SqlException , it's not good enough. 对于一个非常简单的异常类型来说,这几乎可以,但是对于像SqlException这样的复杂类型,这还不够好。

My suggested solution is: create your own dedicated data contract to pass back the data from SqlException that you require, then throw that instead. 我建议的解决方案是:创建自己的专用数据协定以从所需的SqlException中传回数据,然后将其抛出。 In fact, do this for all exception types, it's more secure and better practice. 实际上,对所有异常类型都这样做,这是更安全和更好的做法。 I use Enterprise Library Exception Shielding to handle this automatically. 我使用Enterprise Library Exception Shielding自动处理此问题。 All that gets passed back to the client is a single GUID value identifying the error data in the server log. 返回给客户端的所有信息都是一个GUID值,用于标识服务器日志中的错误数据。

Alternatively, if you are determined to go down the exception route, see this detailed article . 或者,如果您确定要遵循异常路线,请参阅此详细文章

I ran into this problem because I had a breakpoint in the wrong place. 我遇到了这个问题,因为在错误的位置有一个断点。 I removed all breakpoints with Debug..Delete all Breakpoints ( Ctrl-Alt-F9 ), and all of the CommunicationException exceptions disappeared and were replaced with the correct messages coming back. 我用Debug..Delete all Breakpoints删除了所有断点。 Debug..Delete all BreakpointsCtrl-Alt-F9 ),所有CommunicationException异常都消失了,并替换为返回的正确消息。

Yes, the timeout is 60 seconds, so this never should have occurred, so it was probably some weird artifact of Visual Studio 2012. 是的,超时时间为60秒,因此永远都不会发生,因此这可能是Visual Studio 2012的一些怪异产物。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM