Wcf 如果消息大小大于服务(服务器端)接受的大小,如何捕获异常/故障?

Wcf 如果消息大小大于服务(服务器端)接受的大小,如何捕获异常/故障?,wcf,.net-4.5,Wcf,.net 4.5,起初,我认为如果我添加了的实现,可能会在对限制进行任何检查之前拦截消息大小。我很快发现,事实并非如此。运行的服务显然确保在较低级别上强制执行此规则。现在我很好奇,是否有一种方法可以在服务器级别捕获这样的异常,并向客户机返回响应。作为ServiceBehavior的实现会起作用吗 也许更普遍的问题是:是否可以在服务器级别跟踪这一点 还值得注意的是,我并不是WSDL的控制者。您所能做的最好的事情(以及通常的监控方式)是在消息级别启用日志记录。 问题是必须在客户端和服务器上设置maxMessageS

起初,我认为如果我添加了的实现,可能会在对限制进行任何检查之前拦截消息大小。我很快发现,事实并非如此。运行的服务显然确保在较低级别上强制执行此规则。现在我很好奇,是否有一种方法可以在服务器级别捕获这样的异常,并向客户机返回响应。作为ServiceBehavior的实现会起作用吗

也许更普遍的问题是:是否可以在服务器级别跟踪这一点

还值得注意的是,我并不是WSDL的控制者。

您所能做的最好的事情(以及通常的监控方式)是在消息级别启用日志记录。


问题是必须在客户端和服务器上设置maxMessageSize属性。因此,如果消息太大,无法在客户端发送或接收,服务器将不知道这一点。

在较低级别(传输级别)验证消息大小

没有一种简单的方法可以捕获该异常(WCF提供的用于处理异常的IErrorHandling接口在此级别不起作用)

一种方法是创建自己的自定义wcf传输通道(参见示例)

请参见下文中超出配额时生成的异常的样子-您可以看到这是从低级别(HttpChannelListener)抛出的

System.ServiceModel.ProtocolException,System.ServiceModel,版本=4.0.0.0,区域性=neutral,PublicKeyToken=b77a5c561934e089
已超过传入消息(225)的最大消息大小配额。要增加配额,请在相应的绑定元素上使用MaxReceivedMessageSize属性。
位于System.ServiceModel.Channels.HttpInput.ThrowHttpProtocolException(字符串消息、HttpStatusCode状态代码、字符串状态描述)
在System.ServiceModel.Channels.HttpInput.ThrowmaxReceivedMessageSizeExceed()处
位于System.ServiceModel.Channels.HttpInput.GetMessageBuffer()处
位于System.ServiceModel.Channels.HttpInput.ParseMessageAsyncResult.DecodeBufferedMessageAsync()处
位于System.ServiceModel.Channels.HttpInput.ParseMessageAsyncResult.BeginParse()处
位于System.ServiceModel.Channels.HttpInput.BeginParseIncomingMessage(HttpRequestMessage HttpRequestMessage、AsyncCallback回调、对象状态)
位于System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.BeginParseIncomingMessage(异步回调异步回调,对象状态)
位于System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult..ctor(ReplyChannelAcceptor acceptor,Action dequeuedCallback,HttpPipeline管道,AsyncCallback回调,对象状态)
位于System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.BeginProcessInboundRequest(ReplyChannelAcceptor ReplyChannelAcceptor,Action dequeuedCallback,AsyncCallback回调,对象状态)
位于System.ServiceModel.Channels.HttpChannelListener`1.HttpContextReceivedAsyncResult`1.ProcessHttpContextAsync()
位于System.ServiceModel.Channels.HttpChannelListener`1.BeginHttpContextReceived(HttpRequestContext上下文、操作acceptorCallback、AsyncCallback回调、对象状态)
位于System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult结果)
在System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandlerRequest()中
在System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()中
位于System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(对象状态)
在System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32错误代码,UInt32个字节,NativeOverlapped*NativeOverlapped)
在System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32错误,UInt32字节读取,NativeOverlapped*NativeOverlapped)
在System.Threading.\u IOCompletionCallback.PerformiCompletionCallback(UInt32错误代码,UInt32个字节,本机重叠*pOVERLAP)

我当然同意客户端/服务器端的问题。在我的情况下,有一个WSDL,在该WSDL中,遵从性要求服务器作为响应的一部分发回SOAP消息对于服务器来说太大。这有点奇怪,因为WCF已经处理了为此返回的异常,但现在需要进行操纵,以便服务器知道发生了此异常,以便向客户端返回错误报告。
<ExceptionType>System.ServiceModel.ProtocolException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>The maximum message size quota for incoming messages (225) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element.</Message>
<StackTrace>
at System.ServiceModel.Channels.HttpInput.ThrowHttpProtocolException(String message, HttpStatusCode statusCode, String statusDescription)
at System.ServiceModel.Channels.HttpInput.ThrowMaxReceivedMessageSizeExceeded()
at System.ServiceModel.Channels.HttpInput.GetMessageBuffer()
at System.ServiceModel.Channels.HttpInput.ParseMessageAsyncResult.DecodeBufferedMessageAsync()
at System.ServiceModel.Channels.HttpInput.ParseMessageAsyncResult.BeginParse()
at System.ServiceModel.Channels.HttpInput.BeginParseIncomingMessage(HttpRequestMessage httpRequestMessage, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.BeginParseIncomingMessage(AsyncCallback asynCallback, Object state)
at System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult..ctor(ReplyChannelAcceptor acceptor, Action dequeuedCallback, HttpPipeline pipeline, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.HttpPipeline.EmptyHttpPipeline.BeginProcessInboundRequest(ReplyChannelAcceptor replyChannelAcceptor, Action dequeuedCallback, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.HttpChannelListener`1.HttpContextReceivedAsyncResult`1.ProcessHttpContextAsync()
at System.ServiceModel.Channels.HttpChannelListener`1.BeginHttpContextReceived(HttpRequestContext context, Action acceptorCallback, AsyncCallback callback, Object state)
at System.ServiceModel.Activation.HostedHttpTransportManager.HttpContextReceived(HostedHttpRequestAsyncResult result)
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.HandleRequest()
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.BeginRequest()
at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.OnBeginRequest(Object state)
at System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
at System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>