WCF MsmqIntegrationBinding - Some XML messages not being picked up - c#

I am using a WCF service to pick up messages off of MSMQ. I have found that some of the messages are not being picked up and I am not sure why. How can I try to debug this? I don't see any errors being thrown, the service is just not picking up messages off o the queue. I am using MsmqMessage to enqueue / dequeue the messages.
Message size: 146,000 bytes (not that big).
What I have found: if I cut down the message size (delete some of the content). So it could be size related or it could be content. Nothing crazy in the xml though.
Any ideas?
Service Configuration:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<!-- use appSetting to configure MSMQ queue name -->
<add key="QueueName" value=".\private$\MyMessageQueue" />
<add key="baseAddress" value="http://localhost:8000/test/message" />
</appSettings>
<system.serviceModel>
<services>
<service behaviorConfiguration="MessageServiceBehavior" name="WcfServiceClient.MessageServiceClient">
<!-- .Net endpoint-->
<endpoint address="msmq.formatname:DIRECT=OS:.\private$\MyMessageQueue"
binding="msmqIntegrationBinding"
bindingConfiguration="DotNetBinding"
contract="WcfServiceClient.IMessageProcessor" />
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MessageServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata />
<!--<serviceThrottling maxConcurrentCalls="20" maxConcurrentSessions="20" />-->
<serviceTimeouts />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<msmqIntegrationBinding>
<binding serializationFormat="ActiveX" name="ActiveXBinding" durable="true" exactlyOnce="true">
<security mode="None" />
</binding>
<binding serializationFormat="Xml" name="DotNetBinding" durable="true" exactlyOnce="true">
<security mode="None" />
</binding>
</msmqIntegrationBinding>
</bindings>
</system.serviceModel>
</configuration>
EDIT:
When I turn on tracing (Just figured this out) I get this? Doesn't make any sense to me?
<E2ETraceEvent xmlns="http://schemas.microsoft.com/2004/06/E2ETraceEvent">
<System xmlns="http://schemas.microsoft.com/2004/06/windows/eventlog/system">
<EventID>131075</EventID>
<Type>3</Type>
<SubType Name="Error">0</SubType>
<Level>2</Level>
<TimeCreated SystemTime="2011-12-28T20:32:42.8874263Z" />
<Source Name="System.ServiceModel" />
<Correlation ActivityID="{00000000-0000-0000-0000-000000000000}" />
<Execution ProcessName="WcfServiceClient.vshost" ProcessID="6316" ThreadID="12" />
<Channel />
<Computer>MyComputer</Computer>
</System>
<ApplicationData>
<TraceData>
<DataItem>
<TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Error">
<TraceIdentifier>http://msdn.microsoft.com/en-US/library/System.ServiceModel.Diagnostics.ThrowingException.aspx</TraceIdentifier>
<Description>Throwing an exception.</Description>
<AppDomain>WcfServiceClient.vshost.exe</AppDomain>
<Source>System.ServiceModel.Channels.TransportReplyChannelAcceptor+TransportReplyChannel/58366981</Source>
<Exception>
<ExceptionType>System.ServiceModel.CommunicationObjectAbortedException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>The communication object, System.ServiceModel.Channels.TransportReplyChannelAcceptor+TransportReplyChannel, cannot be used for communication because it has been Aborted.</Message>
<StackTrace>
at System.ServiceModel.Channels.CommunicationObject.ThrowIfAborted()
at System.ServiceModel.Channels.InputQueueChannel`1.EndDequeue(IAsyncResult result, TDisposable& item)
at System.ServiceModel.Channels.ReplyChannel.EndTryReceiveRequest(IAsyncResult result, RequestContext& context)
at System.ServiceModel.Dispatcher.ReplyChannelBinder.EndTryReceive(IAsyncResult result, RequestContext& requestContext)
at System.ServiceModel.Dispatcher.ErrorHandlingReceiver.EndTryReceive(IAsyncResult result, RequestContext& requestContext)
at System.ServiceModel.Dispatcher.ChannelHandler.AsyncMessagePump(IAsyncResult result)
at System.ServiceModel.Dispatcher.ChannelHandler.OnAsyncReceiveComplete(IAsyncResult result)
at System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
at System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
at System.Runtime.InputQueue`1.AsyncQueueReader.Set(Item item)
at System.Runtime.InputQueue`1.Shutdown(Func`1 pendingExceptionGenerator)
at System.ServiceModel.Channels.InputQueueChannel`1.OnClosing()
at System.ServiceModel.Channels.CommunicationObject.Abort()
at System.ServiceModel.Dispatcher.ListenerHandler.AbortChannels()
at System.ServiceModel.Dispatcher.ListenerHandler.OnAbort()
at System.ServiceModel.Channels.CommunicationObject.Abort()
at System.ServiceModel.Dispatcher.ChannelDispatcher.OnAbort()
at System.ServiceModel.Channels.CommunicationObject.Abort()
at System.ServiceModel.ServiceHostBase.OnServiceHostFaulted(Object sender, EventArgs args)
at System.ServiceModel.Channels.CommunicationObject.OnFaulted()
at System.ServiceModel.Channels.CommunicationObject.Fault()
at System.ServiceModel.ServiceHostBase.OnChannelDispatcherFaulted(Object sender, EventArgs e)
at System.ServiceModel.Channels.CommunicationObject.OnFaulted()
at System.ServiceModel.Channels.CommunicationObject.Fault()
at System.ServiceModel.Dispatcher.ChannelDispatcher.OnListenerFaulted(Object sender, EventArgs e)
at System.ServiceModel.Channels.CommunicationObject.OnFaulted()
at System.ServiceModel.Channels.CommunicationObject.Fault()
at System.ServiceModel.Channels.Msmq4PoisonHandler.InternalFinalDisposition(MsmqQueue disposeFromQueue, MsmqMessageProperty messageProperty)
at System.ServiceModel.Channels.Msmq4PoisonHandler.FinalDisposition(MsmqMessageProperty messageProperty)
at System.ServiceModel.Channels.MsmqDecodeHelper.DecodeIntegrationDatagram(MsmqIntegrationChannelListener listener, MsmqReceiveHelper receiver, MsmqIntegrationInputMessage msmqMessage, MsmqMessageProperty messageProperty)
at System.ServiceModel.MsmqIntegration.MsmqIntegrationInputChannel.DecodeMsmqMessage(MsmqInputMessage msmqMessage, MsmqMessageProperty property)
at System.ServiceModel.Channels.MsmqInputChannelBase.TryReceive(TimeSpan timeout, Message& message)
at System.ServiceModel.Dispatcher.InputChannelBinder.TryReceive(TimeSpan timeout, RequestContext& requestContext)
at System.ServiceModel.Dispatcher.ErrorHandlingReceiver.TryReceive(TimeSpan timeout, RequestContext& requestContext)
at System.ServiceModel.Dispatcher.ChannelHandler.TryTransactionalReceive(Transaction tx, RequestContext& request)
at System.ServiceModel.Dispatcher.ChannelHandler.TransactedLoop()
at System.ServiceModel.Dispatcher.ChannelHandler.SyncTransactionalMessagePump()
at System.ServiceModel.Dispatcher.ChannelHandler.OnStartSyncMessagePump(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>
<ExceptionString>System.ServiceModel.CommunicationObjectAbortedException: The communication object, System.ServiceModel.Channels.TransportReplyChannelAcceptor+TransportReplyChannel, cannot be used for communication because it has been Aborted.</ExceptionString>
</Exception>
</TraceRecord>
</DataItem>
</TraceData>
</ApplicationData>
</E2ETraceEvent>

The exception
System.ServiceModel.CommunicationObjectAbortedException: The communication object, System.ServiceModel.Channels.TransportReplyChannelAcceptor+TransportReplyChannel, cannot be used for communication because it has been Aborted.
indicates, that the TransportReplyChannel has already been closed.
Can you provide the source code which shows how you read from the queue? Maybe there is an additional read after the queue object has been closed / disposed?

Related

WCF Router - Not Routing

I have a WCF Router in a console application that works well, but I need to host this in Azure. As a result I have been asked to make this as a web app so it can be hosted as an app service.
The Router that I have uses this as a config right now
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<services>
<service name="System.ServiceModel.Routing.RoutingService">
<endpoint
binding="basicHttpBinding"
contract="System.ServiceModel.Routing.IRequestReplyRouter"
name="proposalRouter" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:54636/routingService"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceDebug includeExceptionDetailInFaults="true" />
<routing filterTableName="proposalRoutingTableVersion"/>
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding
name="TestBinding"
allowCookies="True"
closeTimeout="00:04:00"
openTimeout="00:00:10"
receiveTimeout="00:05:00"
sendTimeout="00:05:00"
maxReceivedMessageSize="15728640">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<routing>
<namespaceTable>
<add prefix="xxx" namespace="xxxxx"/>
</namespaceTable>
<filters>
<filter name="version_0_9"
filterType="Custom"
filterData="0.9"
customType="RouterService.Asp.VersionFilter, RouterService.Asp"
/>
<filter name="version_1_0"
filterType="Custom"
filterData="1.0"
customType="RouterService.Asp.VersionFilter, RouterService.Asp"
/>
</filters>
<filterTables>
<filterTable name="proposalRoutingTableVersion">
<!--<add filterName="version_0_9" endpointName="version_0_9"/>
<add filterName="version_1_0" endpointName="version_1_0"/>
-->
<!-- Acts as the else clause-->
<!--
<add filterName="noVersion" endpointName="version_0_9"/>-->
<add filterName="version_0_9" endpointName="version_0_9" priority="1"/>
<add filterName="version_1_0" endpointName="version_1_0" priority="0"/>
</filterTable>
</filterTables>
</routing>
<client>
<endpoint address="http://localhost:63690/ProposalService_1_00.svc"
binding="basicHttpBinding"
contract="*"
name="version_1_0"/>
<!--<endpoint address="http://localhost:63690/ProposalService.svc"
binding="basicHttpBinding"
contract="*"
name="version_0_9"/>-->
<!--<endpoint address="http://localhost:63253/ProposalService.svc"
binding="basicHttpBinding"
contract="*"
name="version_0_9"/>-->
</client>
</system.serviceModel>
This drops into the version filter
public class VersionFilter : MessageFilter
{
private string _filterData;
private readonly XNamespace _xmlnsa = "xxxxxx";
public VersionFilter(string filterData)
{
_filterData = filterData;
}
public override bool Match(MessageBuffer buffer)
{
throw new NotImplementedException();
}
public override bool Match(Message message)
{
XDocument doc = XDocument.Parse(message.ToString());
var version = (from xml in doc.Descendants(_xmlnsa + "getProposal")
select xml.Attribute("version")).FirstOrDefault();
return _filterData == version.Value.ToString(); ;
}
}
And then gives the true or false response, then does not hit either of my WebService end points that I am trying to hit.
I have looked in a variety of places for answers on this, but everywhere I have looked show the same \ similar code to what I have in place.
Some suggestions talk about decorating my enums with [EnumMember], so went and added this to every enum. This didnt help.
I have changed from basic to wsHttpBinding, this also did not help, and then I got a 415 error.
I cannot see why \ how changing from a console app to an ASP.Net WCF Application, and an ASP.Net Web Application would cause this to stop working.
In the interested of not missing anything out that I am not seeing this is the response received.
<s:Envelope
xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode
xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault
</faultcode>
<faultstring xml:lang="en-GB">An unexpected failure occurred. Applications should not attempt to handle this error. For diagnostic purposes, this English message is associated with the failure: 'Shouldn't allocate SessionChannels if session-less and impersonating'.</faultstring>
<detail>
<ExceptionDetail
xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<HelpLink i:nil="true"/>
<InnerException i:nil="true"/>
<Message>An unexpected failure occurred. Applications should not attempt to handle this error. For diagnostic purposes, this English message is associated with the failure: 'Shouldn't allocate SessionChannels if session-less and impersonating'.</Message>
<StackTrace> at System.Runtime.Fx.AssertAndThrow(String description)
at System.ServiceModel.Routing.RoutingChannelExtension.get_SessionChannels()
at System.ServiceModel.Routing.RoutingService.GetOrCreateClient[TContract](RoutingEndpointTrait endpointTrait, Boolean impersonating)
at System.ServiceModel.Routing.ProcessRequestAsyncResult`1.StartProcessing()
at System.ServiceModel.Routing.ProcessRequestAsyncResult`1..ctor(RoutingService service, Message message, AsyncCallback callback, Object state)
at System.ServiceModel.Routing.RoutingService.BeginProcessRequest[TContract](Message message, AsyncCallback callback, Object state)
at System.ServiceModel.Routing.RoutingService.System.ServiceModel.Routing.IRequestReplyRouter.BeginProcessRequest(Message message, AsyncCallback callback, Object state)
at AsyncInvokeBeginBeginProcessRequest(Object , Object[] , AsyncCallback , Object )
at System.ServiceModel.Dispatcher.AsyncMethodInvoker.InvokeBegin(Object instance, Object[] inputs, AsyncCallback callback, Object state)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</StackTrace>
<Type>System.Runtime.Fx+InternalException</Type>
</ExceptionDetail>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>
I have tried enabling log, but dont get as far as writing one so not sure what else to try or do.
So, it turns out that this line in the web.config file was the issue
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
removing this line as suggested here https://seroter.com/2010/09/19/lesson-learned-wcf-routing-service-and-the-basichttpbinding/ was the solution to the problem.

WCF service with certificate authentication: "The caller was not authenticated by the service"

I'm trying to setup a WCF service with certificate-based authentication, following this guide: https://msdn.microsoft.com/en-au/library/ff648360.aspx?f=255&MSPPError=-2147217396
I've followed all the steps (I think), which in summary are:
1) Generated a self-signed CA certificate and installed it as a machine-level trusted CA:
2) Generated a certificate for the service (signed by the CA certificate, CN=QvxServiceCert) and installed it at machine-level:
3) configured the WCF service endpoint behavior to use the certificate. My service configuration looks like this:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpointBinding">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="QvxServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceCredentials>
<serviceCertificate findValue="CN=QvxServiceCert" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="esqQvxScheduler.Service.QvxSchedulerAPI" behaviorConfiguration="QvxServiceBehavior">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding"
name="wsHttpEndpoint" bindingName="" contract="esqQvxScheduler.Service.IQvxSchedulerAPI" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/QvxSchedulerAPI/" />
</baseAddresses>
</host>
</service>
</services>
</system.serviceModel>
</configuration>
4) Generated a certificate for the client (again, signed by the CA certificate, this one has CN=QvxClientCert) and installed at user-level:
5) configured the WCF client behavior to use it for authentication. This is my client config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="qvxClientBehavior">
<clientCredentials>
<clientCertificate findValue="CN=QvxClientCert" />
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<wsHttpBinding>
<binding name="wsHttpEndpoint">
<security>
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8733/QvxSchedulerAPI/" binding="wsHttpBinding" behaviorConfiguration="qvxClientBehavior"
bindingConfiguration="wsHttpEndpoint" contract="QvxSchedulerAPI.IQvxSchedulerAPI"
name="wsHttpEndpoint">
<identity>
<certificate encodedValue="[A LONG AUTOGENERATED STRING THE MEANING OF WHICH I HAVE NO IDEA]" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
6) Gave the user that runs the client access to the certificate, by issuing the following on the command line: cacls "C:\Users\MyUsername\AppData\Roaming\Microsoft\Crypto\RSA\S-1-5-21-742627442-1779984360-2302642487-1000" /E /G "MyUser-PC\MyUsername":R
This was all done following the guide, without any issue that I could see. Everything seems ok... but when I try to invoke the service from my client, all I get this frustratingly vague and unhelpful exception:
Unhandled Exception: System.ServiceModel.Security.SecurityNegotiationException: The caller was not authenticated by the service. ---> System.ServiceModel.FaultException: The request for security token could not be satisfied because authentication failed.
at System.ServiceModel.Security.SecurityUtils.ThrowIfNegotiationFault(Message message, EndpointAddress target)
at System.ServiceModel.Security.SspiNegotiationTokenProvider.GetNextOutgoingMessageBody(Message incomingMessage, SspiNegotiationTokenProviderState sspiState)
--- End of inner exception stack trace ---
Server stack trace:
at System.ServiceModel.Security.IssuanceTokenProviderBase`1.DoNegotiation(TimeSpan timeout)
at System.ServiceModel.Security.SspiNegotiationTokenProvider.OnOpen(TimeSpan timeout)
at System.ServiceModel.Security.TlsnegoTokenProvider.OnOpen(TimeSpan timeout)
at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Security.CommunicationObjectSecurityTokenProvider.Open(TimeSpan timeout)
at System.ServiceModel.Security.SymmetricSecurityProtocol.OnOpen(TimeSpan timeout)
at System.ServiceModel.Security.WrapperSecurityCommunicationObject.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.SecurityChannelFactory`1.ClientSecurityChannel`1.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.DoOperation(SecuritySessionOperation operation, EndpointAddress target, Uri via, SecurityToken currentToken, TimeSpan timeout)
at System.ServiceModel.Security.SecuritySessionSecurityTokenProvider.GetTokenCore(TimeSpan timeout)
at System.IdentityModel.Selectors.SecurityTokenProvider.GetToken(TimeSpan timeout)
at System.ServiceModel.Security.SecuritySessionClientSettings`1.ClientSecuritySessionChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.CallOpenOnce.System.ServiceModel.Channels.ServiceChannel.ICallOnce.Call(ServiceChannel channel, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Well, after a lot of trial and error, turns out that you either have to have a CRL installed for your CA or you have to specify explicitly that you don't want a revocation check, by adding this to your behavior's ClientCredentials tag:
<serviceCertificate>
<authentication revocationMode="NoCheck"/>
</serviceCertificate>
and vice-versa for the service side:
<clientCertificate>
<authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck"/>
</clientCertificate>
Also, you need to remove the autogenerated certificate tag in the client and replace it with an instruction to look up the certificate:
<identity>
<certificateReference findValue="CN=QvxServiceCert" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My" />
</identity>

WCF Service - Message / Object size related

I have wcf service (S1) as client and another Wcf service(S2) as server. S1 consume S2 over net.tcp. S2 has one operation, which return a complex object with most of it's contents are string. The average size of this object is between 7-8 MB.
Recently I had to add more string contents to the actual object graph. This cause S2 to return following error
The socket connection was aborted. This could be caused by an error
processing your message or a receive timeout being exceeded by the
remote host, or an underlying network resource issue. Local socket
timeout was '00:05:00'. System.Net.Sockets.SocketException
(0x80004005): An existing connection was forcibly closed by the remote
host at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32
offset, Int32 size, SocketFlags socketFlags) at
System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer,
Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)
However, everything works as expected when I remove some of the string contents from the object graph.
After doing bit of a homework,I was managed to land on a conclusion that, it has something to do with the size of the returned object. This made me to revise my client and service configuration/quota's.
However, I have no luck even after modifying the client and service especially size related attributes.
Can someone guide me on this? Please ask me for more information if needed.
Thanks in advance.
Client (S1)
<netTcpBinding>
<binding name="NetTcp" closeTimeout="00:05:00"
openTimeout="00:05:00" receiveTimeout="00:10:00" sendTimeout="00:05:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="2147483647"
maxBufferSize="2147483647" maxConnections="10" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="None">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
<client>
<endpoint address="net.tcp://xxxxxxxx/xxxxxxService"
binding="netTcpBinding" bindingConfiguration="NetTcp" behaviorConfiguration="RBehavior"
contract="IService" name="NetTcp" />
</client>
<services/>
<behaviors>
<serviceBehaviors>
<behavior name="NSBehavior">
<etwTracking profileName="EndToEndMonitoringProfile"/>
<serviceMetadata httpGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="RBehavior">
**<dataContractSerializer maxItemsInObjectGraph="2147483647" />**
</behavior>
</endpointBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
Server (S2)
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="netTcp" closeTimeout="00:03:00"
openTimeout="00:03:00" receiveTimeout="00:10:00" sendTimeout="00:03:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="20000000"
maxBufferSize="20000000" maxConnections="10" maxReceivedMessageSize="20000000">
<readerQuotas maxDepth="32" maxStringContentLength="20000000"
maxArrayLength="20000000" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="None">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="Engine.Rules"
behaviorConfiguration="REServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="net.tcp://xxxxx:8005/Service"/>
</baseAddresses>
</host>
<endpoint address=""
binding="netTcpBinding" bindingConfiguration="netTcp"
contract="Ixxxx" />
<endpoint address="mex"
binding="mexTcpBinding"
contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="REServiceBehavior">
<serviceMetadata httpGetEnabled="false"/>
**<dataContractSerializer maxItemsInObjectGraph="2147483647"/>**
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceThrottling maxConcurrentSessions="1000"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Update: As per #ErikFunkenbusch's sensible support, I am attaching service trace information.
<ExceptionString>System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:05:00'. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)
--- End of inner exception stack trace ---</ExceptionString>
<InnerException>
<ExceptionType>System.Net.Sockets.SocketException, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType>
<Message>An existing connection was forcibly closed by the remote host</Message>
<StackTrace>
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)
</StackTrace>
<ExceptionString>System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)</ExceptionString>
<NativeErrorCode>2746</NativeErrorCode>
</InnerException>
</Exception>
Have you tried increasing the send and receive timeout values? You're sending a lot of data over the wire (7-8MB) and 5 seconds may not be enough time to complete that transaction. Try setting them to something like 30 seconds and then working from there.
E:
<binding name="netTcp" closeTimeout="00:30:00"
openTimeout="00:30:00" receiveTimeout="00:30:00" sendTimeout="00:30:00">
That is what I'm referring to, specifically.

Error while accessing Custom STS(WCF Service) on Azure

I've a custom STS having active federation endpoint that works well on local box.
Local Url is "https://localhost/CustomIDP/Service.svc"
After hosting on Azure on the final step of acquiring SAML token I am getting the following error while acquiring token from STS:
[System.ServiceModel.CommunicationException]
{"An error occurred while receiving the HTTP response to "https://mysts.cloudapp.net/Service.svc". 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."}
InnerException:
[System.Net.WebException]: {"The underlying connection was closed: An unexpected error occurred on a receive."}
InnerException:
[System.IO.IOException]:{"Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host."}
InnerException:
[System.Net.Sockets.SocketException]: {"An existing connection was forcibly closed by the remote host"}: 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)
Appreciate any inputs. Please find below the code snippet used for calling the STS for acquiring SAML token. The error occurs at channel.Issue statement.
using (var factory = new WSTrustChannelFactory(
new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
new EndpointAddress(new Uri(stsEndpoint))))
{
factory.Credentials.UserName.UserName = username;
factory.Credentials.UserName.Password = password;
factory.TrustVersion = TrustVersion.WSTrust13;
WSTrustChannel channel = null;
try
{
var rst = new RequestSecurityToken
{
RequestType = WSTrust13Constants.RequestTypes.Issue,
AppliesTo = new EndpointAddress(realm),
KeyType = KeyTypes.Bearer,
};
channel = (WSTrustChannel)factory.CreateChannel();
return channel.Issue(rst);
}
finally
{
if (channel != null)
{
channel.Abort();
}
factory.Abort();
}
}
Service Configuration for STS service hosted on Azure:
<system.serviceModel>
<services>
<service name="Microsoft.IdentityModel.Protocols.WSTrust.WSTrustServiceContract" behaviorConfiguration="ServiceBehavior">
<endpoint address="" binding="ws2007HttpBinding" contract="Microsoft.IdentityModel.Protocols.WSTrust.IWSTrust13SyncContract" bindingConfiguration="ws2007HttpBindingConfiguration"/>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<ws2007HttpBinding>
<binding name="ws2007HttpBindingConfiguration">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" establishSecurityContext="false" />
</security>
</binding>
</ws2007HttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
<serviceCredentials>
<serviceCertificate x509FindType="FindByThumbprint" findValue="[thumbprint]" storeLocation="LocalMachine" storeName="My" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
<microsoft.identityModel>
<service>
<!-- User name and password are not authenticated by windows authentication but a custom verification is done -->
<securityTokenHandlers>
<remove type="Microsoft.IdentityModel.Tokens.WindowsUserNameSecurityTokenHandler, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<add type="ActiveIdPSite.CustomUserNameSecurityTokenHandler, ActiveIdPSite" />
</securityTokenHandlers>
<serviceCertificate>
<certificateReference x509FindType="FindByThumbprint" findValue="[thumbprint]" storeLocation="LocalMachine" storeName="My" />
</serviceCertificate>
<certificateValidation certificateValidationMode="None" />
</service>
</microsoft.identityModel>
The issue is solved. Root cause was related to certificates.
1.Enable WCF Diagnostics while deploying.
2.Get the svclog file and open with Microsoft Service Trace viewer.
Here's the extract from svclog.
Replying to an operation threw a exception:
System.NotSupportedException - The private key is not present in the X.509 certificate
Since the certificate didn't have private key in exportable format, it failed to read the private key.
Used the fix mentioned here:
http://social.msdn.microsoft.com/Forums/en/Geneva/thread/2b2681af-838e-4f22-84fa-b5494b9dcc02

System.Security.Cryptography.CryptographicException: The parameter is incorrect

I have the following exception when a try create a new Instance of ServiceHost (new ServiceHost(serviceType, baseAddresses))
System.Security.Cryptography.CryptographicException: The parameter is incorrect.
Stack Trace:
[CryptographicException: The parameter is incorrect.
]
System.Security.Cryptography.X509Certificates.X509Certificate2Collection.LoadStoreFromBlob(Byte[] rawData, String password, UInt32 dwFlags, Boolean persistKeyContainers) +1871625
System.Security.Cryptography.X509Certificates.X509Certificate2Collection.Import(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags) +104
System.ServiceModel.Description.ConfigLoader.LoadIdentity(IdentityElement element) +501
System.ServiceModel.Description.ConfigLoader.LoadServiceDescription(ServiceHostBase host, ServiceDescription description, ServiceElement serviceElement, Action`1 addBaseAddress) +12346988
System.ServiceModel.ServiceHostBase.LoadConfigurationSectionInternal(ConfigLoader configLoader, ServiceDescription description, ServiceElement serviceSection) +67
System.ServiceModel.ServiceHostBase.ApplyConfiguration() +108
System.ServiceModel.ServiceHostBase.InitializeDescription(UriSchemeKeyedCollection baseAddresses) +192
System.ServiceModel.ServiceHost.InitializeDescription(Type serviceType, UriSchemeKeyedCollection baseAddresses) +49
System.ServiceModel.ServiceHost..ctor(Type serviceType, Uri[] baseAddresses) +151
STARTAccessPoint.StartServiceFactory.CreateServiceHost(Type serviceType, Uri[] baseAddresses) in D:\Work\Projects\Marlo\LIME\projecto_start\start\project\START\STARTAccessPoint\accesspointService.svc.cs:273
System.ServiceModel.Activation.ServiceHostFactory.CreateServiceHost(String constructorString, Uri[] baseAddresses) +422
System.ServiceModel.HostingManager.CreateService(String normalizedVirtualPath) +1461
System.ServiceModel.HostingManager.ActivateService(String normalizedVirtualPath) +44
System.ServiceModel.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath) +651
[ServiceActivationException: The service '/accesspointService.svc' cannot be activated due to an exception during compilation. The exception message is: The parameter is incorrect.
.]
System.Runtime.AsyncResult.End(IAsyncResult result) +688590
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result) +190
System.ServiceModel.Activation.ServiceHttpModule.EndProcessRequest(IAsyncResult ar) +310694
System.Web.AsyncEventExecutionStep.OnAsyncEventCompletion(IAsyncResult ar) +94
Here is the code that I use:
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
if (!CertificatesConfiguration.HasServiceCredentials(serviceType.FullName))
{
throw new ConfigurationErrorsException(String.Format("Config section does not contain service credentials for service \"{0}\".", serviceType.FullName));
}
var credentials = CertificatesConfiguration.ServiceCredentials.ByServiceName(serviceType.FullName);
//X509Certificate cert = credentials.ServiceCertificate.Certificate;
return InitServiceHost(new ServiceHost(serviceType, baseAddresses),typeof(STARTAccessPoint.Resource),credentials.ServiceCertificate.Certificate);
}
This is my Web.Config :
<services>
<service name="STARTAccessPoint.accesspointService" behaviorConfiguration="SecureServiceBehavior">
<endpoint address="" name="ResourceBindingPort" binding="customBinding" bindingNamespace="http://www.w3.org/2009/02/ws-tra" bindingConfiguration="SecureServiceBinding" contract="STARTAccessPoint.Resource">
<identity>
<certificate encodedValue=""/>
</identity>
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="SecureServiceBehavior">
<serviceMetadata httpsGetEnabled="true" externalMetadataLocation="https://localhost:1443/accesspointService.wsdl.xml"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="SecureClientBehavior">
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<customBinding>
<binding name="SecureServiceBinding" closeTimeout="00:01:30" openTimeout="00:01:30" sendTimeout="00:01:30" receiveTimeout="00:01:30">
<reliableSession ordered="true" reliableMessagingVersion="WSReliableMessaging11" flowControlEnabled="false" maxRetryCount="4" inactivityTimeout="00:01:00"/>
<security defaultAlgorithmSuite="Basic128" allowSerializedSigningTokenOnReply="true" authenticationMode="MutualCertificate" requireDerivedKeys="false" securityHeaderLayout="Lax" messageProtectionOrder="SignBeforeEncrypt" messageSecurityVersion="WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10" requireSignatureConfirmation="false">
<issuedTokenParameters keyType="SymmetricKey"/>
<secureConversationBootstrap/>
</security>
<httpsTransport authenticationScheme="Anonymous" hostNameComparisonMode="WeakWildcard" proxyAuthenticationScheme="Anonymous"/>
</binding>
</customBinding>
</bindings>
Cerificates Config File, with all information about the Certificates:
<?xml version="1.0" encoding="UTF-8"?>
<peppol.certificates>
<validation>
<add name="MyRootCertificates"
rootCACertificateThumbprint=""
intermediateAcessPointCACertificateThumbprint="‎"/>
</validation>
<serviceCredentials>
<add serviceName="SecureClient_at_localhost">
<serviceCertificate
findValue="‎7a6fa503ab57b81d6318a51ca265e739a51ce660"
x509FindType="FindByThumbprint"
storeName="Root"
storeLocation="LocalMachine" />
</add>
<add serviceName="*">
<serviceCertificate
findValue="‎7a6fa503ab57b81d6318a51ca265e739a51ce660"
x509FindType="FindByThumbprint"
storeName="Root"
storeLocation="LocalMachine" />
</add>
</serviceCredentials>
<clientCredentials>
<add endpointName="SecureClient_at_localhost">
<clientCertificate
filename="c:\localhost.cer"
password="" />
<serviceCertificate
findValue="‎7a6fa503ab57b81d6318a51ca265e739a51ce660"
x509FindType="FindByThumbprint"
storeName="Root"
storeLocation="LocalMachine" />
</add>
<add endpointName="*">
<clientCertificate
filename="c:\localhost.cer"
password="" />
<serviceCertificate
filename="c:\localhost.cer"
password="" />
</add>
</clientCredentials>
</peppol.certificates>
Can you help?
Based on the error message, the certificate referenced in the config file is incorrect.
Here is a good set of instructions from Microsoft on how to configure and use certificates.
I am sure this does not always work, but I resolved this by rebooting Visual Studio, reopen your application, select Build -> Clean Solution, Rebuild and then run.

Categories

Resources