当抛出FaultException时WCF抛出CommunicationException
解决方案:
一些跟踪显示抛出了 CommunicationException,因为我的异常 T 未正确序列化存在问题;因为,在两层深处,我有一个匿名类型的对象,它是不可序列化的。删除它并冒泡更改似乎可以修复它。在此之前我还做了一些小事情,但我一辈子都不记得那是什么了,只是它没有在配置中完成。
我从我的痕迹中收到消息,例如:
Type 'RebuiltWCFService.Requests.HelloWorldRequest' with data contract name 'HelloWorldRequest:http://schemas.datacontract.org/2004/07/RebuiltWCFService.Requests' is not expected.
Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
原始帖子
我今天遇到了一个看似奇怪的问题,我只是找不到答案!
问题:当我抛出FaultException 时,我的服务抛出CommunicationException!如果我不抛出异常,它不会执行此操作。
在我的服务中,我正确地定义了错误契约:
[OperationContract]
[FaultContract(typeof(Faults.HelloWorldFault))]
Responses.HelloWorldResponse HelloWorld(Requests.HelloWorldRequest parameter);
然后在错误条件下我抛出正确类型的异常:
if (_errors.Count() > 0)
{
Faults.HelloWorldFault fault = new Faults.HelloWorldFault(_errors);
throw new FaultException<Faults.HelloWorldFault>(fault, new FaultReason("There are one or more errors in the request. Check the 'Errors' property for more detaisl"));
}
然后我在客户端捕获它:
try
{
response = client.HelloWorld(new BasicService.HelloWorldRequest() { Number = 49 });
client.Close();
Console.WriteLine(String.Format("Response message: {0}, Response number: {1}", response.Message, response.Number));
}
catch (FaultException<BasicService.HelloWorldFault> ex)
{
...
}
这一切对我来说似乎都不错,并且喜欢它应该有效。然而,一旦我去测试我的错误子句(通过提供错误的数据,例如缺失的字段),整个事情就在我身上消失了。当我抛出FaultException 时,服务会抛出CommunicationException 并显示以下消息:
An error occurred while receiving the HTTP response to http://localhost:8732/Design_Time_Addresses/RebuiltWCFService/Service1/.
This could be due to the service endpoint binding not using the HTTP protocol.
This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down).
See server logs for more details.
有人可以对此提供一些见解吗?我正在使用 basicHttp 绑定,并且还尝试使用 wsHttp。我将根据要求发布我的配置文件。
Solution:
A bit of tracing showed the CommunicationException was being thrown because there was an issue with my exception T not serializing correctly; because, two layers deep, I had an anonymously typed object, which was unserializable. Removing it and bubbling up the changes appeared to fix it. There was somethinge else small I did before that, but I can't remember for the life of me what it was, only that it wasn't done in the config.
I was getting messages from my traces such as:
Type 'RebuiltWCFService.Requests.HelloWorldRequest' with data contract name 'HelloWorldRequest:http://schemas.datacontract.org/2004/07/RebuiltWCFService.Requests' is not expected.
Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
Original post
I've encountered a seemingly strange issue today that I just cant't find an answer to!
The problem: my service is throwing a CommunicationException when I throw a FaultException! It does not do this if I don't throw an exception.
In my service, I'm properly defining the fault contracts:
[OperationContract]
[FaultContract(typeof(Faults.HelloWorldFault))]
Responses.HelloWorldResponse HelloWorld(Requests.HelloWorldRequest parameter);
Then under error conditions I'm throwing an exception of the correct type:
if (_errors.Count() > 0)
{
Faults.HelloWorldFault fault = new Faults.HelloWorldFault(_errors);
throw new FaultException<Faults.HelloWorldFault>(fault, new FaultReason("There are one or more errors in the request. Check the 'Errors' property for more detaisl"));
}
And then I'm catching it on the client end:
try
{
response = client.HelloWorld(new BasicService.HelloWorldRequest() { Number = 49 });
client.Close();
Console.WriteLine(String.Format("Response message: {0}, Response number: {1}", response.Message, response.Number));
}
catch (FaultException<BasicService.HelloWorldFault> ex)
{
...
}
That all seems OK to me, and like it should work. However, as soon as I go to test my error clauses (by providing bad data, such as a missing field), the whole thing dies on me. When I throw my FaultException, the service instead throws a CommunicationException with the message
An error occurred while receiving the HTTP response to http://localhost:8732/Design_Time_Addresses/RebuiltWCFService/Service1/.
This could be due to the service endpoint binding not using the HTTP protocol.
This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down).
See server logs for more details.
Can anybody offer some insight on this one? I am using the basicHttp binding, and I've also tried it with wsHttp. I will post my config file upon request.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
FaultException 是 CommunicationException 的子级。所以你的代码中发生的事情没有任何问题。
如果您在处理时不确定异常是什么,通常会报告为 CommunicationException。如果您想以自己的方式处理特定异常,请使用以下结构。
在上面的结构中,Exception 是 CommunicationException 的父级。 CommunicationException 是FaultException 等的父类。
A FaultException is a child of CommunicationException. So there is nothing wrong in what's happening in your code.
If you are uncertain about what the exception is while handling, it is usually reported as CommunicationException. If you want to handle your specific exception in your own way, use the following structure.
In the above structure, Exception is parent of CommunicationException. CommunicationException is the parent of FaultException and so on.
谢谢大家,你们帮助我更好地理解了这个问题。我的观察:我保留了一个 List MyData - 来保存任何通用/动态集合,但无法序列化,因此导致关闭连接,因此出现通信异常。
当我从故障合约中删除列表并抛出故障样式时,它显然给出了故障合约异常,而不是通信异常。
希望有帮助,
HydTechie。
Thanks guys, you helped me to understand the issue in a better way. My observation: I kept a List MyData - to hold any generic/dynamic collection, that was unable to serialize, so resulting to close the connection, so the communication exception.
When I removed the List from Fault Contract, and throw Fault style, it was clearly giving Fault contract exception, instead of communication exception.
Hope it helps,
HydTechie.
我遇到这个问题是因为我在错误的位置有一个或多个断点。我使用
Debug..Delete all Breakpoints
(Ctrl-Alt-F9
)删除了所有断点,并且所有 CommunicationException 异常都消失了,并被返回的正确消息所取代。是的,超时时间是 60 秒,所以这根本不应该发生,因此这可能是 Visual Studio 2012 的一些奇怪的产物。
I ran into this problem because I had one or more breakpoints 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.Yes, the timeout is 60 seconds, so this never should have occurred, so it was probably some weird artifact of Visual Studio 2012.