Asynchronous WCF fails with MessageSecurityException when multiple worker processes (Web Garden) - wcf

I have a simple WCF service using ws2007HttpBinding which puts in a configurable delay, then returns. The service is configured to be PerCall. The service is hosted on IIS 7.5 on Windoes 2008 Server R2 SP1
I am call this asynchronously via console app using an imported service reference.
I can easily inject 10000 requests and they are all successful. Each request uses a new WCF proxy. The CPU was running about 70%
I wanted to see if adding another worker process would help throughput and utilise the full 100% cpu. I configured it to have 2 worker processes.
When I ran this it began to fail virtually immediately with a MessageSecurityException. Even if I set the number of requsts to 10, it still fails. I noticed that it fails more if the timer in the WCF service is short ( between 10 and 50 ms). A higher delay causes less failures.
It either fails on the proxy.Open() or proxy.Close()
I investigated this and thought it might be related to secure conversation. So I disabled this by
setting
establishSecurityContext="false"
(Is this correct?) I am confused why this would be the case if I am creating a new proxy each time
This dis not seem to make any difference.
When I return the AppPool to have only 1 worker process it works again
Has anybody had the same issue, and managed to get a solution. If so can you post you solution in explicit detail.
The errors received are as follows
In the WCF trace it reported
The incoming message is not part of an existing security session
The exception shown in trace
System.ServiceModel.EndpointNotFoundException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
There was no channel that could accept the message with action 'http://tempuri.org/ILoadedService/RunLoad'.
at System.ServiceModel.Dispatcher.ErrorBehavior.ThrowAndCatch(Exception e, Message message)
at System.ServiceModel.Channels.DatagramChannelDemuxer2.ProcessItem(TInnerItem item)
at System.ServiceModel.Channels.DatagramChannelDemuxer2.HandleReceiveResult(IAsyncResult result)
at System.ServiceModel.Channels.DatagramChannelDemuxer2.OnReceiveComplete(IAsyncResult result)
at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
at System.ServiceModel.Channels.ReplyChannel.HelpReceiveRequestAsyncResult.OnReceiveRequest(IAsyncResult result)
at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
at System.Runtime.InputQueue1.AsyncQueueReader.Set(Item item)
at System.Runtime.InputQueue1.EnqueueAndDispatch(Item item, Boolean canDispatchOnThisThread)
at System.Runtime.InputQueue1.EnqueueAndDispatch(T item, Action dequeuedCallback, Boolean canDispatchOnThisThread)
at System.ServiceModel.Channels.SingletonChannelAcceptor`3.Enqueue(QueueItemType item, Action dequeuedCallback, Boolean canDispatchOnThisThread)
at System.ServiceModel.Channels.HttpChannelListener.HttpContextReceived(HttpRequestContext context, Action callback)
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)
System.ServiceModel.EndpointNotFoundException: There was no channel that could accept the message with action 'http://tempuri.org/ILoadedService/RunLoad'.
Exception caught on the client
Exception thrown of type [System.ServiceModel.Security.MessageSecurityException] Source [mscorlib]
Exception when receiving response [9] - Message [An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.] StackTrace [
Server stack trace:
at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result)
at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeEndService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at SimpleIISTestClient.SlowClient.ILoadedService.EndRunLoad(IAsyncResult result)
at SimpleIISTestClient.Program.PerfAsynchCallback(IAsyncResult result) in C:\CRF Prototypes\Load\SimpleIISTestClient\Program.cs:line 116]
Inner Exception [9] - Message [The security context token is expired or is not valid. The message was not processed.] StackTrace []

Related

How to resolve a name conversion failure when sending MSMQ messages

I've recently been following this article on how to set up a 3-party queueing system with MSMQ, wherein the publisher, queue server and subscriber are all on separate systems within an Active Directory domain. I've succeeded in completing Part 1 and the first half of Part 2. However, when I continue with the latter half of Part 2 and enable Transport security, I receive the following error: An error occurred when converting the 'mymsmqservermachine.mydomain.network.ads\private$\Path/To/MyQueuedService.svc' queue path name to the format name: Unrecognized error -1072824300 (0xc00e0014). All operations on the queued channel failed. Ensure that the queue address is valid. MSMQ must be installed with Active Directory integration enabled and access to it is available.
I've verified the following:
Active Directory Integration for MSMQ is enabled on all the machines in the 3-party system, per this StackOverflow post.
The URL to the queue remains exactly the same as it was prior to enabling security, which worked just fine, no parsing errors whatsoever.
I've following the instructions provided by Windows when installing MSMQ here.
The relevant parts of the stack trace I get are:
at System.ServiceModel.Channels.MsmqFormatName.FromQueuePath(String queuePath)
at System.ServiceModel.Channels.MsmqUri.ActiveDirectory.UriToFormatName(Uri uri)
at System.ServiceModel.Channels.MsmqOutputChannel.OpenQueue()
--- End of inner exception stack trace ---
Server stack trace:
at System.ServiceModel.Channels.MsmqOutputChannel.OpenQueue()
at System.ServiceModel.Channels.MsmqOutputChannel.OnOpenCore(TimeSpan timeout)
at System.ServiceModel.Channels.MsmqOutputChannel.OnBeginOpen(TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.CommunicationObject.OpenAsyncResult.InvokeOpen()
at System.ServiceModel.Channels.CommunicationObject.OpenAsyncResult..ctor(CommunicationObject communicationObject, TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.CommunicationObject.BeginOpen(TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.ServiceChannel.OnBeginOpen(TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.CommunicationObject.OpenAsyncResult.InvokeOpen()
at System.ServiceModel.Channels.CommunicationObject.OpenAsyncResult..ctor(CommunicationObject communicationObject, TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.CommunicationObject.BeginOpen(TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.BeginCall(ServiceChannel channel, TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.BeginCallOnce(TimeSpan timeout, CallOnceManager cascade, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.ServiceChannel.BeginEnsureOpened(TimeSpan timeout, AsyncCallback callback, Object state)
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.StartEnsureOpen(Boolean completedSynchronously)
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.FinishEnsureInteractiveInit(IAsyncResult result, Boolean completedSynchronously)
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.StartEnsureInteractiveInit()
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.Begin()
at System.ServiceModel.Channels.ServiceChannel.BeginCall(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, TimeSpan timeout, AsyncCallback callback, Object asyncState)
at System.ServiceModel.Channels.ServiceChannel.BeginCall(ServiceChannel channel, ProxyOperationRuntime operation, Object[] ins, AsyncCallback callback, Object asyncState)
at System.Threading.Tasks.TaskFactory`1.FromAsyncImpl[TArg1,TArg2,TArg3](Func`6 beginMethod, Func`2 endFunction, Action`1 endAction, TArg1 arg1, TArg2 arg2, TArg3 arg3, Object state, TaskCreationOptions creationOptions)
at System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.CreateTask(ServiceChannel channel, ProxyOperationRuntime operation, Object[] inputParameters)
at System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.CreateTask(ServiceChannel channel, IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
Based on the content of the stack trace, it appears that the failure is coming from resolving the queue name within Active Directory. I've tried the following to attempt to resolve such a failure:
Simplifying the name to contain no periods or slashes (didn't work)
Using a public queue instead of a private queue, in the event that this step was omitted from the original tutorial on MSDN (it wasn't, didn't work)
At this point, I'm out of ideas. Has anybody encountered this error when using WCF with net.msmq bindings before and solved their issue ?
EDIT: When running the following test code from the same machine and same user, I'm able to send a message to the queue perfectly fine:
Me.TestContext.WriteLine("Executing under user '{0}'", WindowsIdentity.GetCurrent().Name)
Dim msg = New System.Messaging.Message()
msg.Body = "This is a test message"
msg.Label = "Test Message"
msg.Formatter = new ActiveXMessageFormatter()
Dim queue = new MessageQueue("FormatName:DIRECT=OS:mymsmqservermachine.mydomain.network.ads\private$\Path/To/MyQueuedService.svc")
queue.Send(msg)
By pure fluke, I stumbled across the solution, and I recorded it in my blog.
The gist of the solution was that I had to add a DNS identity for my WCF endpoint binding in my client:
Dim endpointAddress = New EndpointAddress(queueUri, EndpointIdentity.CreateDnsIdentity(queueUri.Host))
Dim netMsmqBinding = New NetMsmqBinding With
{
.Durable = true,
.ExactlyOnce = false,
.UseActiveDirectory = false,
.Security = New NetMsmqSecurity With
{
.Mode = NetMsmqSecurityMode.Transport
}
}
Return New ChannelFactory(Of ICwteCentralPublishingServiceChannel)(netMsmqBinding, endpointAddress)
I apologize to the world for the Visual Basic code, it's a legacy application and wasn't my choice.

Routing of Self-Hosted WCF Service

I have a self hosted WCF service that listens on port 80 (the third-party device does not support sending on other ports). I also have two web sites and three Web API base services that are also on port 80 and have been working well. All of these services/sites run using different FQDNs (test-svc1.example.com, test-svc2.example.com, test-site1.example.com, etc..). It is important to note that all the subdomains point to the same IP Address on the server. All of this has been working great until I try and install my service that hosts my WCF service. Once I install that service when I attempt to navigate to either of my two sites I get a page with the following information on it:
.....
You have created a service.
To test this service, you will need to create a client and use it to call the service. You can do this using the svcutil.exe tool from the command line with the following syntax:
.....
If I stop my WCF based service then my site works fine.
The following is the code that is used to host the WCF service.
public class MyService
{
private const string MyServiceName = "MyService";
private ServiceHost _selfHost;
public void Start()
{
this._selfHost = new ServiceHost(typeof(MyWebService), new Uri(wcf.exampe.com));
try
{
BasicHttpBinding binding = new BasicHttpBinding();
int tempValue = 0;
this._selfHost.AddServiceEndpoint(typeof(IMyServiceContract), binding, MyServiceName);
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
this._selfHost.Description.Behaviors.Add(smb);
this._selfHost.Open();
}
catch ( CommunicationException ce )
{
this._selfHost.Abort();
}
}
public void Stop()
{
// Close the ServiceHostBase to shutdown the service.
this._selfHost.Close();
}
}
This code is called by a windows service wrapper. What I need is for this service to be able to run on port 80, but only listen for packets associated with wcf.example.com.
--------- EVENT VIEWER Information
I have enabled debugging and tracing in the Event Viewer to see if that would help me isolate the issue. The following is are a few of the items from there.
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Microsoft-Windows-Application Server-Applications" Guid="{c651f5f6-1c0d-492e-8ae1-b4efd7c9d503}" />
<EventID>57396</EventID>
<Version>0</Version>
<Level>3</Level>
<Task>0</Task>
<Opcode>0</Opcode>
<Keywords>0x2000000000010000</Keywords>
<TimeCreated SystemTime="2013-08-16T20:52:13.956945800Z" />
<EventRecordID>99</EventRecordID>
<Correlation ActivityID="{1E2ADE87-F4FC-4B42-8711-DD49B2F0DB6B}" />
<Execution ProcessID="1716" ThreadID="4828" ProcessorID="0" KernelTime="0" UserTime="3" />
<Channel>Microsoft-Windows-Application Server-Applications/Analytic</Channel>
<Computer>MyComputer</Computer>
<Security UserID="S-1-5-18" />
</System>
<EventData>
<Data Name="data1">System.ServiceModel 4.0.0.0</Data>
<Data Name="data2">System.ServiceModel.ProtocolException: There is a problem with the XML that was received from the network. See inner exception for more details. ---> System.Xml.XmlException: The body of the message cannot be read because it is empty. --- End of inner exception stack trace ---</Data>
<Data Name="SerializedException">
<Exception>
<ExceptionType>System.ServiceModel.ProtocolException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
</ExceptionType>
<Message>There is a problem with the XML that was received from the network. See inner exception for more details.
</Message>
<StackTrace> at System.Runtime.Diagnostics.EtwDiagnosticTrace.WriteExceptionToTraceString(XmlTextWriter xml, Exception exception, Int32 remainingLength, Int32 remainingAllowedRecursionDepth) at System.Runtime.Diagnostics.EtwDiagnosticTrace.ExceptionToTraceString(Exception exception, Int32 maxTraceStringLength) at System.Runtime.Diagnostics.EtwDiagnosticTrace.GetSerializedPayload(Object source, TraceRecord traceRecord, Exception exception, Boolean getServiceReference) at System.Runtime.TraceCore.ThrowingException(EtwDiagnosticTrace trace, String param0, String param1, Exception exception) at System.Runtime.ExceptionTrace.TraceException[TException](TException exception, String eventSource) at System.Runtime.ExceptionTrace.AsError(Exception exception) at System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult.CompleteParseAndEnqueue(IAsyncResult result) at System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult.HandleParseIncomingMessage(IAsyncResult result) at System.Runtime.AsyncResult.SyncContinue(IAsyncResult result) 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.Channels.SharedHttpTransportManager.EnqueueContext(IAsyncResult listenerContextResult) at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContextCore(IAsyncResult listenerContextResult) at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContext(IAsyncResult result) at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result) at System.Net.LazyAsyncResult.Complete(IntPtr userToken) at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken) at System.Net.ListenerAsyncResult.IOCompleted(ListenerAsyncResult asyncResult, UInt32 errorCode, UInt32 numBytes) at System.Net.ListenerAsyncResult.WaitCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
<ExceptionString>System.ServiceModel.ProtocolException: There is a problem with the XML that was received from the network. See inner exception for more details. ---&gt; System.Xml.XmlException: The body of the message cannot be read because it is empty. --- End of inner exception stack trace ---
</ExceptionString>
<InnerException>
<Exception>
<ExceptionType>System.Xml.XmlException, System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
</ExceptionType>
<Message>The body of the message cannot be read because it is empty.
</Message>
<StackTrace> at System.Runtime.Diagnostics.EtwDiagnosticTrace.WriteExceptionToTraceString(XmlTextWriter xml, Exception exception, Int32 remainingLength, Int32 remainingAllowedRecursionDepth) at System.Runtime.Diagnostics.EtwDiagnosticTrace.GetInnerException(Exception exception, Int32 remainingLength, Int32 remainingAllowedRecursionDepth) at System.Runtime.Diagnostics.EtwDiagnosticTrace.WriteExceptionToTraceString(XmlTextWriter xml, Exception exception, Int32 remainingLength, Int32 remainingAllowedRecursionDepth) at System.Runtime.Diagnostics.EtwDiagnosticTrace.ExceptionToTraceString(Exception exception, Int32 maxTraceStringLength) at System.Runtime.Diagnostics.EtwDiagnosticTrace.GetSerializedPayload(Object source, TraceRecord traceRecord, Exception exception, Boolean getServiceReference) at System.Runtime.TraceCore.ThrowingException(EtwDiagnosticTrace trace, String param0, String param1, Exception exception) at System.Runtime.ExceptionTrace.TraceException[TException](TException exception, String eventSource) at System.Runtime.ExceptionTrace.AsError(Exception exception) at System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult.CompleteParseAndEnqueue(IAsyncResult result) at System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult.HandleParseIncomingMessage(IAsyncResult result) at System.Runtime.AsyncResult.SyncContinue(IAsyncResult result) 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.Channels.SharedHttpTransportManager.EnqueueContext(IAsyncResult listenerContextResult) at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContextCore(IAsyncResult listenerContextResult) at System.ServiceModel.Channels.SharedHttpTransportManager.OnGetContext(IAsyncResult result) at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result) at System.Net.LazyAsyncResult.Complete(IntPtr userToken) at System.Net.LazyAsyncResult.ProtectedInvokeCallback(Object result, IntPtr userToken) at System.Net.ListenerAsyncResult.IOCompleted(ListenerAsyncResult asyncResult, UInt32 errorCode, UInt32 numBytes) at System.Net.ListenerAsyncResult.WaitCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped) at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
</StackTrace>
<ExceptionString>System.Xml.XmlException: The body of the message cannot be read because it is empty.
</ExceptionString>
</Exception>
</InnerException>
</Exception>
</Data>
<Data Name="AppDomain">MyService.exe</Data>
</EventData>
</Event>
----------------- End Error
The transport sent a message to 'http://x.x.x.8/data/MyService'.
Handling an exception. Exception details: System.ServiceModel.ProtocolException: There is a problem with the XML that was received from the network. See inner exception for more details. ---> System.Xml.XmlException: The body of the message cannot be read because it is empty.
--- End of inner exception stack trace ---
at System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult.CompleteParseAndEnqueue(IAsyncResult result)
at System.ServiceModel.Channels.HttpPipeline.EnqueueMessageAsyncResult.HandleParseIncomingMessage(IAsyncResult result)
at System.Runtime.AsyncResult.SyncContinue(IAsyncResult result)
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.HttpChannelListener1.HttpContextReceivedAsyncResult1.ProcessHttpContextAsync()
HttpGetContext start.
--------- EVENT VIEWER Information
As mentioned before, all of this works fine on my test box when running under Visual Studio, but does not work when run on my production box as a service.
Regards,
Richard O

How to catch exception/fault where message size is larger than accepted by the service (server side)?

At first, I thought if I added an implementation of IDispatchMessageInspector, that perhaps this would intercept the message size before any checking on the limit is done. I soon found, this is not the case. The running service obviously makes sure to enforce this rule on a lower level. Now I am curious if there is a way in which I can capture such an exception on the server level and return a response to the client. Would the an implementation of IErrorHandler as a ServiceBehavior do the trick?
Maybe the more general question is: Can this be tracked at the server level?
It may also be worth noting that I am not in control of the WSDL.
The message size is verified at the lower level - at the transport level.
There isn't a easy way to catch that exception (The IErrorHandling interface provided by WCF to handle exceptions doesn't work at this level).
One way would be to create your own custom wcf transport channel (see here an example)
See below how the generated exception looks like when the quota is exceeded - you can see that this is thrown from the low level (HttpChannelListener).
<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>
The best you can do (and the usual way of monitoring this) is to enable logging at the message level.
http://geekswithblogs.net/mnf/archive/2008/10/03/use-wcf-message-logging.aspx
the problem is that the maxMessageSize properties must be set on both client and server. So if the message is too large to be sent or received on the client side, your server will not know about this.

The I/O operation has been aborted because of either a thread exit or an application request

I'm running some WCF net.tcp services on a high-traffic website.
In my local environment everything worked as expect.
In the production environment, the website works for few minutes then the service throw an exception.
When I stop and start again the service website it works again for few minutes.
Here's the details:
A TCP error (995: The I/O operation has been aborted because of either a thread exit or an application request) occurred while transmitting data.
System.ServiceModel.Channels.SocketConnection.EndRead()
System.ServiceModel.Channels.TracingConnection.EndRead()
System.ServiceModel.Channels.ConnectionStream.ReadAsyncResult.OnAsyncReadComplete(Object state)
System.ServiceModel.Channels.TracingConnection.TracingConnectionState.ExecuteCallback()
System.ServiceModel.Channels.SocketConnection.AsyncReadCallback(Boolean haveResult, Int32 error, Int32 bytesRead)
System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
The I/O operation has been aborted because of either a thread exit or an application request
I see the same problem on Win8kR2SP1Web:
System.Runtime.InteropServices.COMException (0x800703E3): The I/O operation has been aborted because of either a thread exit or an application request. (Exception from HRESULT: 0x800703E3)
An error occurred while communicating with the remote host. The error code is 0x800703E3.
The I/O operation has been aborted because of either a thread exit or an application request. (Exception from HRESULT: 0x800703E3)
at System.Web.Hosting.IIS7WorkerRequest.RaiseCommunicationError(Int32 result, Boolean throwOnDisconnect)
at System.Web.Hosting.IIS7WorkerRequest.ReadEntityCoreSync(Byte[] buffer, Int32 offset, Int32 size)
at System.Web.HttpRequest.GetEntireRawContent()
at System.Web.HttpRequest.FillInFormCollection()
at System.Web.HttpRequest.get_Form()
at System.Web.Mvc.HttpRequestExtensions.GetHttpMethodOverride(HttpRequestBase request)
at System.Web.Mvc.AcceptVerbsAttribute.IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
at System.Linq.Enumerable.All[TSource](IEnumerable`1 source, Func`2 predicate)
at System.Web.Mvc.ActionMethodSelector.RunSelectionFilters(ControllerContext controllerContext, List`1 methodInfos)
at System.Web.Mvc.ReflectedControllerDescriptor.FindAction(ControllerContext controllerContext, String actionName)
at System.Web.Mvc.ControllerActionInvoker.FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, String actionName)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
at System.Web.Mvc.Controller.ExecuteCore()
at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<>c__DisplayClassb.<BeginProcessRequest>b__5()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0()
at System.Web.Mvc.MvcHandler.<>c__DisplayClasse.<EndProcessRequest>b__d()
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionSt ep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
First time in 1 year though ...

weird error about WCF -- System.ServiceModel.CommunicationException was unhandled

I created a simple WCF demo:
Server Side:
namespace ServerSide
{
class Program
{
static void Main(string[] args)
{
System.ServiceModel.ServiceHost host =
new System.ServiceModel.ServiceHost(typeof(HelloIndigo.HelloIndigoService), new Uri("http://locahost:8000/HelloIndigo"));
host.AddServiceEndpoint(typeof(HelloIndigo.IHelloIndigoService), new System.ServiceModel.BasicHttpBinding(), "HelloIndigoService");
host.Open();
Console.Write("Terminate Server");
Console.ReadLine();
}
}
}
Client Side:
namespace ClientSide
{
class Program
{
static void Main(string[] args)
{
System.ServiceModel.EndpointAddress ep =
new System.ServiceModel.EndpointAddress("http://locahost:8000/HelloIndigo/HelloIndigoService");
IHelloIndigoService proxy =
System.ServiceModel.ChannelFactory<IHelloIndigoService>.CreateChannel(new System.ServiceModel.BasicHttpBinding(), ep);
string s = proxy.HelloIndigo();
Console.WriteLine(s);
Console.ReadLine();
}
}
}
Then, run ServerSide, when I tried to run the CLientSide, I got following error msg:
An error occurred while receiving the HTTP response to http://locahost:8000/HelloIndigo/HelloIndigoService. 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.
And the error details:
System.ServiceModel.CommunicationException was unhandled
Message="An error occurred while receiving the HTTP response to http://locahost:8000/HelloIndigo/HelloIndigoService. 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."
Source="mscorlib"
StackTrace:
Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ProcessGetResponseWebException(WebException webException, HttpWebRequest request, HttpAbortReason abortReason)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at ClientSide.IHelloIndigoService.HelloIndigo()
at ClientSide.Program.Main(String[] args) in E:\My_Test\Test_for_VS2008\WCF_TestLessonOne_Client\ClientSide\Program.cs:line 16
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: System.Net.WebException
Message="The underlying connection was closed: An unexpected error occurred on a receive."
Source="System"
StackTrace:
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
InnerException: System.IO.IOException
Message="Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."
Source="System"
StackTrace:
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.PooledStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.Connection.SyncRead(HttpWebRequest request, Boolean userRetrievedStream, Boolean probeRead)
InnerException: System.Net.Sockets.SocketException
Message="An existing connection was forcibly closed by the remote host"
Source="System"
ErrorCode=10054
NativeErrorCode=10054
StackTrace:
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
InnerException:
Is your machine called locahost ?? Typically, those machines are called localhost - so try this Url for your service (both on server and client side):
new Uri("http://localhost:8000/HelloIndigo")
With this change, I was able to re-create your sample without any issues whatsoever.