I have a WCF service hosted in IIS7 (the service and client configuration is at the end of this post). I have run across an odd scenario that I was hoping someone might have some ideas about how to attack it and find a solution.
The service only exposes one contract, 'ProcessMessage'. I can send/receive synchronous messages from the service using that contract just fine with expected performance, but one particular call to that contract returns more than 65KB of data; about 1 MB. Upon originally calling it, I received the expected max receive size exceeded error. So I increased the maxReceivedMessageSize, and now this particular call takes 40 minutes to return to the client. This is well beyond any of the timeout settings, and well beyond what I would expect it to take. The server side processing time is only 2 seconds. It appears to be held up on the client side.
I've also tried bumping up several of the other quotas in the file to no avail.
Any thoughts would be greatly appreciated. Thanks.
Service Config:
<system.serviceModel>
<services>
<service behaviorConfiguration="Lrs.Esf.Facade.Startup.FacadeBehavior"
name="Lrs.Esf.Facade.Startup.FacadeService">
<endpoint address="" binding="wsHttpBinding" bindingConfiguration="default" contract="Lrs.Esf.Facade.Startup.IFacadeService">
<identity>
<servicePrincipalName value="lrsdomain/PensionDev" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="default">
<security mode="None"/>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="Lrs.Esf.Facade.Startup.FacadeBehavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true" />
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
Client Config:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IFacadeService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:1:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="52428800" maxReceivedMessageSize="6553600"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="None">
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://esf2.facade.testpe.pg.local/FacadeWcf/FacadeService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IFacadeService"
contract="FacadeServiceReference.IFacadeService" name="WSHttpBinding_IFacadeService">
<identity>
<servicePrincipalName value="lrsdomain/PensionDev" />
</identity>
</endpoint>
</client>
You didn't increase the size of the various parameters on the server side, it seems - you should definitely try that! Use the binding configuration from your client config file on the server side as well - the service might well be choking since it's still defaulting to 64K message size.
Also, the receiveTimeout in your client binding is a bit funny - it's missing a zero digit:
<binding name="WSHttpBinding_IFacadeService"
receiveTimeout="00:1:00"
You should use receiveTimeout="00:01:00"
Marc
I have figured out the basic cause of the issue and a work-around, however additional insight would be great.
The DataSet was getting serialized in XML format by WCF. I forced the DataSet to serialize as a byte[] and the time reduced to 4 seconds. One guess is that escaping all of the characters in 4MB of XML so that the HTTP communication was valid is what caused the problem.
Related
We have a WCF service with 4 service method & running well for last 4 years. Now client has requirement for a new service method which may return 10K to 1 million record. We have tested it with separate service and found that size of response xml is about 36MB to 200 MB and processing time it takes about 4 sec to 7-8 sec. We have made following changed in client webconfig file-
<bindings>
<basicHttpBinding>
<binding name="wsHttpBinding"
maxReceivedMessageSize="2147483647"
</binding>
</basicHttpBinding>
</bindings>
We have a fear that if we add this service method in existing service and changed maxReceivedMessageSize to max it may impact the memory consumption for whole service. And in case of simultaneous method call it may result out of memory kind of exception.
But client want to have this new service method in existing service. Please suggest what possible solution we can have. Client dont want to steam the information and sending as a zip file as for that they have to set up separate FTP location.
Thank,
#Niru
<system.serviceModel>
<bindings>
<basicHttpBinding>
<!-- Create a custom binding for our service to enable sending large amount of data -->
<binding name="MyBasicHttpBinding"
maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647"
maxBufferSize="2147483647">
<readerQuotas
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxDepth="2147483647"
maxNameTableCharCount="2147483647"
maxStringContentLength="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<!-- Enable the serializer to serialize greater number of records -->
<behavior name="SilverlightWCFLargeDataApplication.Web.SilverlightWCFServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false"/>
<services>
<!-- Bind the WCF service to our custom binding -->
<service behaviorConfiguration="SilverlightWCFLargeDataApplication.Web.SilverlightWCFServiceBehavior"
name="SilverlightWCFLargeDataApplication.Web.SilverlightWCFService">
<endpoint address="" binding="basicHttpBinding"
bindingConfiguration="MyBasicHttpBinding"
contract="SilverlightWCFLargeDataApplication.Web.SilverlightWCFService"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
</system.serviceModel>
Read this article, maybe your answer.
https://smehrozalam.wordpress.com/2009/01/29/retrieving-huge-amount-of-data-from-wcf-service-in-silverlight-application/
i use WCF with Code First (VS 2012, .NET 4.0, WCF 5). Everything works fine unless i want to transfer an large object. It contains a list of many other objects. Every object has only small content. If this list is longer than 127 objects, i get an exception:
The server did not provide a meaningful reply; this might be caused by
a contract mismatch, a premature session shutdown or an internal
server error.
I found that out by reducing column count in database (try and error).
I use the following configuration on the client:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_****_Service" closeTimeout="00:00:10"
openTimeout="00:00:10" receiveTimeout="00:05:00" sendTimeout="00:05:00"
maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:8000/****" binding="netTcpBinding"
bindingConfiguration="****" contract="****"
name="NetTcpBinding_****Service">
<identity>
<userPrincipalName value="****" />
</identity>
</endpoint>
</client>
</system.serviceModel>
The server configuration looks as follows:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_****_Service" closeTimeout="00:00:10"
openTimeout="00:00:10" receiveTimeout="00:05:00" sendTimeout="00:05:00"
transferMode="Buffered" maxBufferPoolSize="2147483647" maxBufferSize="2147483647"
maxConnections="0" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="100000" maxStringContentLength="100000"
maxArrayLength="100000" maxBytesPerRead="100000" maxNameTableCharCount="100000" />
<reliableSession enabled="false" />
</binding>
</netTcpBinding>
</bindings>
<services>
<service name="****">
<endpoint address="" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_****_Service"
contract="****" />
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="net.tcp://localhost:8000/****" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="false"/>
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Please excuse the masking of some names. I need to avoid that one can draw inferences from these names about the project. :D
At first, set this property on server side (just for dev)
<serviceDebug includeExceptionDetailInFaults="true" />
that specifies whether to include managed exception information in the detail of SOAP faults returned to the client for debugging purposes.
It's sure there is something wrong when processing your request but you don't have any debug information. That's why you have to set this property. You can also turn on WCF Tracing but it's a bit more difficult.
WCF have many quotas : A quota is a hard limit that prevents the use of additional resources once the quota value is exceeded.
There are especially two quotas you need to be aware when sending large data : maxReceivedMessageSize and MaxItemsInObjectGraph.
I am using Message security and windows credential type. I am not using streaming and Mtom for some reason right now but might consider in the future. So far WCF service documentation specifies that you can transfer max up to 2GB of data. I am thinking if I can transfer 20-40 MB of data according to WCF specification, that will work for me now even though this is bad for now.
I can transfer data up to 10MB from WCF Service to Client but when I try to increase more than 10MB something is stopping it from transferring data from server to client and I don't know what.
I am transferring collection of objects from Web Service to Client.
When data doesn't transfer from Server to Client, I don't get any error message, this is very weird. When I set below transfer sizes to 10MB in client and server binding properties, I can transfer around collection of 1650 objects but when its around 1900, I don't get anything on client ???? WHY ????
Just to make it work I set all require property to max and its still not working.
Below is what I have in Client:
<ws2007HttpBinding>
<binding name="CustomizeWs2007HttpBinding" sendTimeout="00:10:00" closeTimeout="00:10:00"
openTimeout="00:10:00" messageEncoding="Text" receiveTimeout="00:10:00"
maxBufferPoolSize="0"
maxReceivedMessageSize="2147483647"
>
<readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="4096" />
<security mode="Message">
<message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true"/>
</security>
</binding></ws2007HttpBinding>
Below is what I have in WCF Service(Server):
<ws2007HttpBinding>
<binding name="KerberosBinding" maxBufferPoolSize="0" maxReceivedMessageSize="2147483647"
messageEncoding="Text" sendTimeout="00:10:00" closeTimeout="00:10:00"
openTimeout="00:10:00">
<readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="4096" />
<security>
<message negotiateServiceCredential="true" establishSecurityContext="true"/>
</security>
</binding></ws2007HttpBinding>
I hope somebody has an answer.
Thank you so much in advance.
Thank you Chris, its working now and Thank you for all others for your response.
I am a new member to this site so don't know where to put my final solution, anyway its pasted below:.
15728640 = 15MB
10485760 = 10MB though its too big
Client Config:
<behaviors>
<endpointBehaviors>
<behavior name="PServiceBehavior">
<dataContractSerializer maxItemsInObjectGraph="10485760"/>
</behavior>
</endpointBehaviors>
</behaviors>
and reference it from endpoint:
<endpoint address="http://localhost:53054/pservicehost/pservice.svc"
binding="ws2007HttpBinding" bindingConfiguration="PServiceWs2007HttpBinding" behaviorConfiguration="PServiceBehavior"
contract="PWebServiceContract.IPService" name="PServiceWs2007HttpBindingEndPoint">
Service Config:
<behaviors>
<serviceBehaviors>
<behavior name="PServiceHost.PServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<dataContractSerializer maxItemsInObjectGraph="10485760"/>
</behavior>
</serviceBehaviors>
</behaviors>
and reference it from service:
<services>
<service behaviorConfiguration="PServiceHost.PServiceBehavior" name="PWebService.PService">
<endpoint address="" binding="ws2007HttpBinding" bindingConfiguration="KerberosBinding" contract="PWebServiceContract.IPService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
Maybe it has something to do with this throttle setting:
<dataContractSerializer maxItemsInObjectGraph="..."/>
I suggest you turn on WCF tracing on the server. It is a very useful tool. It helped me a lot in the past, especially if there are burried exceptions on the server side that you can't easily detect anywhere else.
Here is the link that explains how to turn it on: Service Trace Viewer Tool (SvcTraceViewer.exe)
Searched with no luck...
I keep getting
The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element.
It makes sense, so I go into both Server and client config and make the change:
Client
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IFileUpload"
closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" transferMode="Streamed" messageEncoding="Text" maxBufferSize="65536" maxReceivedMessageSize="67108864">
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/services/FileUpload.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IFileUpload"
contract="CFTW.FileUpload.IFileUpload" name="BasicHttpBinding_IFileUpload" />
</client>
</system.serviceModel>
Server
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IFileUpload"
transferMode="Streamed" messageEncoding="Text" maxBufferSize="67108864" maxBufferPoolSize="67108864" maxReceivedMessageSize="67108864">
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="BasicHttpBinding_IFileUpload">
<endpoint address="~/services/FileUpload.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IFileUpload"
contract="CFTW.FileUpload.IFileUpload"></endpoint>
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
I'm not sure why it's not working (otherwise I'd fix it:)). It's running on .NET 4.0 RC.
I just ran into this issue. I found that my custom binding did not get applied at all. Then I used name = "" in binding tag. Then everything started working with the new settings. This is due to .NET 4.0 comes with default binding/endpoint/behavior configurations. These default settings have name = "". I just modified the default binding itself. The reason for my custom binding(named) did not get applied is due to the value for the name in <service> tag. It should follow <Namespace.ServiceClassName>.
You need to increase the attribute maxReceivedMessageSize in the client config for the binding. Also, be sure to set the same value for the maxBufferSize. For buffered connection these two values need to be same.
Had the same problem, luckily in a second project and could compare with the working project. The difference was that the working project had additional attributes set in the web.config for the service bindings...
Working sample:
httpsTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"
The second project only had:
httpsTransport
Also do a search in your project for 65536 as it is also defined in configuration.svcinfo and configuration91.svcinfo of the service reference.
I'm trying to host a WCF Service with binding "wsDualHttpBinding". When I run my client and service(hosted in IIS) from the same machine it works fine. But, when I host the service in a different machine my client fails to register with the service. The following errors are coming...
[System.ServiceModel.Security.SecurityNegotiationEception]
The caller was not authenticated by
the service. And inner exception: The
request for security token could not
be satisfied because authentication
failed.
When trying to run from a different machine in another workgroup the following error appears
"Client is unable to finish the
security negotiation within the
configured time(00:00:00)"
In the IIS6.0 I turned off the Integrated Authentication and allowed anonymous access.
My Service's Web.Config follows:
<system.serviceModel>
<diagnostics>
<messageLogging logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true"/>
</diagnostics>
<bindings>
<wsDualHttpBinding>
<binding name="StatTickerHttpBinding" bypassProxyOnLocal="false" useDefaultWebProxy="true" receiveTimeout="23:59:59">
<reliableSession ordered="true" inactivityTimeout="00:30:00"/>
</binding>
</wsDualHttpBinding>
</bindings>
<services>
<service name="StatTickerService" behaviorConfiguration="ServiceBehavior">
<!-- Service Endpoints -->
<endpoint address="" binding="wsDualHttpBinding" bindingConfiguration="StatTickerHttpBinding" contract="IBroadCastService">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
<identity>
<dns value="localhost"/>
</identity> -->
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
My Client App.Config follows...
<system.serviceModel>
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_StatTickerBroadcastService"
closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
<reliableSession ordered="true" inactivityTimeout="00:30:00"/>
<security mode="Message">
<message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default"/>
</security>
</binding>
</wsDualHttpBinding>
</bindings>
<client>
<endpoint address="http://192.168.100.77/TPS.StatTicker.WCFservice/Service.svc" binding="wsDualHttpBinding"
bindingConfiguration="WSDualHttpBinding_StatTickerBroadcastService"
contract="BroadcastGateway.StatTickerBroadcastService"
name="WSDualHttpBinding_StatTickerBroadcastService">
<identity>
<servicePrincipalName value="host/192.168.100.77"/>
</identity>
</endpoint>
</client>
</system.serviceModel>
The Client side config is done by using svcutil.
I searched and tried all the solutions given in the google for the past 4 days but no luck. Please help urgently.
If I understand your issue, it sounds like you're having problems with delegation.
Here's what I think you're trying to do:
User connects to web service
User authenticates with windows authentication (kerberos)
Webserver impersonates user
Webserver connects to backend via WCF
Webserver authenticates with backend using the user's credentials (kerberos)
Backend accepts credentials and serves up data
What needs to happen is your backend has to trust your web server to act on your behalf, called delegation. This is controlled by the domain and not freely given.
If both machines are on the same domain, the domain controller has to configure the web server as able to delegate for users. Without this, no machines on the network will trust your web server acting on a user's behalf. If this all takes place on the same machine, it does its own delegation.
If both machines are in a workgroup, I don't know what you would do.
I think you need to specify a security of "none" in the server's web.config. Otherwise it would default to insisting on an authentication mechanism.
Try this:
<identity>
<servicePrincipalName value=""/>
</identity>