WCF Streaming not able to transfer large files - wcf

I am making a WCF Service for transfering files. I have only basic WCF understanding and followed the MSDN tutorial: WCF Tutorial
I started using byte arrays for transfering the files but as soon as the files got a little big (100kb was enough) it would fail with bad request.
I followed another guide and changed to streaming with messages, and it works with small files as well but fails with bigger ones like the old version. I suspect the fault lies in my config file as the one generated by svcutil.exe doesn't say anything about streaming.
This is my clients app.config:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IDocPublisher" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="200000000" maxReceivedMessageSize="200000000"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="200000000" maxStringContentLength="200000000" maxArrayLength="200000000"
maxBytesPerRead="200000000" maxNameTableCharCount="200000000" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8000/ServiceModelSamples/docPublisherWebService/docPublisher"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IDocPublisher"
contract="IDocPublisher" name="WSHttpBinding_IDocPublisher">
<identity>
<userPrincipalName value="Emil-PC\Emil" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
And this is the servers app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"
httpHelpPageEnabled="true" />
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="serviceBehavior"
name="DocPublisher">
<endpoint address="http://localhost:8000/ServiceModelSamples/docPublisherWebService"
name="basicHttpStream"
binding="basicHttpBinding"
bindingConfiguration="httpLargeMessageStream"
contract="IDocPublisher" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="httpLargeMessageStream"
maxReceivedMessageSize="200000000"
maxBufferSize="200000000"
transferMode="Streamed"
messageEncoding="Mtom" />
</basicHttpBinding>
</bindings>
</system.serviceModel>
</configuration>

Try to increase send timeout and reader quotas on client side, set buffer size on server side.

Turns out the config files weren't the real problem, the problem was that the servers app.config was never used as the msdn tutorial doesn't use app.config but creates the endpoints in the main method.

Related

WCF SOAP service returns Not Found for a large request and works OK for a smaller one

I have a SilverLight application that calls WCF service by POST via SSL and sends large request. Everything works OK on a local machine with a self-signed certificate. Moreover, it works on a remote server but only for a small request. When the application make a POST request (using SOAP) for a big scope of data I get a CommunicationException: "The remote server returned an error: NotFound." The same use case on the local machine with absolutely the same web.config file (except of the sql connection string) works without the issue. It seems that the problem in the IIS configuration. I tried to investigate IIS logs but did not find any information about the requests as something before the logging kernel rejected the request. I have read a lot of articles where people propose different settings of the endpoints bindings, tried them but have not achieved success.
My configuration of the services is the next:
<system.web>
<httpRuntime maxRequestLength="2097151"/>
<!--...(other settings) -->
</system.web>
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="2147483647" />
</requestFiltering>
</security>
</system.webServer>
<system.serviceModel>
<services>
<!--... (other services)-->
<service name="SD.Web.Services.ClientUser.UserLayersService">
<endpoint address="soap"
binding="basicHttpBinding"
contract="SD.Web.Services.ClientUser.IUserLayersService" />
<endpoint address="json"
behaviorConfiguration="SD.Web.Services.AspNetAjaxBehavior"
binding="webHttpBinding"
contract="SD.Web.Services.ClientUser.IUserLayersService" />
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding maxReceivedMessageSize="2097152"
maxBufferSize="2097152"
maxBufferPoolSize="2097152">
<security mode="Transport" />
</binding>
</webHttpBinding>
<basicHttpBinding>
<binding maxReceivedMessageSize="2097152"
maxBufferSize="2097152"
maxBufferPoolSize="2097152">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="SD.Web.Services.AspNetAjaxBehavior">
<webHttp defaultBodyStyle="Bare"
defaultOutgoingResponseFormat="Json"
automaticFormatSelectionEnabled="false"
faultExceptionEnabled="true" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
I found the answer using Fiddler 4. Reader quotas have to be set.
<bindings>
<webHttpBinding>
<binding maxReceivedMessageSize="2097152"
maxBufferSize="2097152"
maxBufferPoolSize="2097152">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"/>
<security mode="Transport" />
</binding>
</webHttpBinding>
<basicHttpBinding>
<binding maxReceivedMessageSize="2097152"
maxBufferSize="2097152"
maxBufferPoolSize="2097152">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647"/>
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>

wcf exception: The server did not provide a meaningful reply

I have a service that use the tcp binding and this services allows to the clients interact with the database. I use EF and self tracking entities.
One thing that I want to do is store files in the database, so to not overload the wire, i have two tables with their corresponding entities. One table Documents with the information of the documents (type, size... etc) and other table, Files, that store the binary information, the file.
Well, in local, when I run the client and the service in the same computer, I can store the files that I want. I try with a file of 6MB. But If I run the client in other computer in the same lan, then I have many problems.
For example, if I try to store a small file, 50kB, I don't have problems, but if I try to store the file of 6MB, then I can get different errors.
For example, if I configure in the client a low timeout, for example 1 minute, I get the error:
System.TimeoutException: This request operation sent to net.tcp://192.168.1.5:7997/CMMSHost did not receive a reply within the configured timeout (00:01:00).
If I configure the client to have a timeout of 10 minutes, then I get the following error:
The server did not provide a meaningful reply
The service is hosted in a wpf application, and in the Begin method of the serve that add the document in the database, I send a text with a log to know if the call is received or not. When I get some of the errors, the call in not received, so I think that the problem perhaps is that the self tacking entity for some reason does not arrive to the service.
My app.config for the service is the following:
<endpoint address=""
binding="netTcpBinding"
bindingConfiguration="tcpBinding"
name="NetTcpBindingEndpoint"
contract="GTS.CMMS.Service.IService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint contract="IMetadataExchange" binding="mexTcpBinding" address="net.tcp://localhost:5000/mex" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="behaviorConfig">
<!--
<serviceMetadata httpGetEnabled="true" />-->
<!--Necesario para poder enviar excepciones desde el servicio al cliente.-->
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceThrottling maxConcurrentCalls="100" maxConcurrentSessions="100" />
<serviceMetadata/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="tcpBinding" maxBufferSize="67108864"
maxReceivedMessageSize="67108864" maxBufferPoolSize="67108864"
transferMode="Buffered" closeTimeout="00:00:10"
openTimeout="00:00:10" receiveTimeout="00:20:00"
sendTimeout="00:01:00" maxConnections="100">
<security mode="None"/>
<readerQuotas maxArrayLength="67108864" maxBytesPerRead="67108864" maxStringContentLength="67108864"/>
<reliableSession enabled="true" inactivityTimeout="00:20:00" />
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
And the client configuration is:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:01:00" sendTimeout="00:01:00"
transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288"
maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:20:00"
enabled="true" />
<security mode="None">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://192.168.1.5:7997/CMMSHost" binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_IService" contract="IService"
name="NetTcpBinding_IService" />
</client>
</system.serviceModel>
</configuration>
I use a large readquotes, to try to discard that the problem is the size of the file, but the problem persists.
Thanks.
I don't think this is an issue related to WCF. I assume its rather related to your IIS.
Can you try the following code snippet in your web.config?
<system.webServer>
<security>
<requestFiltering>
<requestLimits maxAllowedContentLength="524288000"/>
</requestFiltering>
</security>
</system.webServer>

WCF Callback Service with netTcp Binding timeout after 10 mins

I'm creating a chat application with WCF(using callback contract) and netTcpBinding.
I'm hosting the service as a windows service and accessing it from other computers
via the client application.
The problem that i'm facing now is the clients connection comes to a Fault state after
10 mins which seems to be some kind of timeout that occur.
I already tried increasing the received timeout and send timeout in both service and client but didn't work.
which setting should i change to increase this timeout period and in which application, service or client?
Following are my configuration files,
Service
<system.serviceModel>
<services>
<service behaviorConfiguration="PeerTalk.Service.ChatServiceBehavior"
name="PeerTalk.Service.ChatService">
<endpoint address="" binding="netTcpBinding" bindingConfiguration=""
contract="PeerTalk.Service.ServiceContracts.IChat">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexTcpBinding" bindingConfiguration=""
contract="IMetadataExchange" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:7920/ChatService" />
<add baseAddress="net.tcp://localhost:7921/ChatService" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="PeerTalk.Service.ChatServiceBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<netTcpBinding>
<binding name="tcpBinding"
maxBufferSize="67108864"
maxReceivedMessageSize="67108864"
maxBufferPoolSize="67108864"
transferMode="Buffered"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:00:10"
sendTimeout="00:00:10"
maxConnections="100">
<readerQuotas maxDepth="64"
maxStringContentLength="67108864"
maxArrayLength="67108864"
maxBytesPerRead="67108864"
maxNameTableCharCount="16384"/>
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows"/>
</security>
<reliableSession enabled="false" inactivityTimeout="00:01:00"/>
</binding>
</netTcpBinding>
</bindings>
</system.serviceModel>
Client
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="NetTcpBinding_IChat" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:00:10" transactionFlow="false"
transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="67108864"
maxBufferSize="67108864" maxConnections="10" maxReceivedMessageSize="67108864">
<readerQuotas maxDepth="32" maxStringContentLength="67108864"
maxArrayLength="67108864" maxBytesPerRead="67108864" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:01:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://10.10.10.45:7921/ChatService" binding="netTcpBinding"
bindingConfiguration="NetTcpBinding_IChat" contract="PeerTalkService.IChat"
name="NetTcpBinding_IChat">
</endpoint>
</client>
</system.serviceModel>
Thanks.
The timeout in this case is defined by both receiveTimeout in the binding and inactivityTimeout in reliable session which is used for duplex messaging. The correct solution is not increasing timeout but implementing some ping / keep alive messages. The reason is that increasing timeout will keep connections open for failed clients.
Can you post client call sample (service call example). What might happening here is that you are not closing client correctly and you reach maximum sessions on service side.
You must be aware that using net.tcp binding is different than http.
You can use System.ServiceModel performance counters (http://msdn.microsoft.com/en-us/library/ms750527.aspx) and see after 10 minutes what is happening (number of calls outstanding, number of service instances, etc..)
http://dkochnev.blogspot.com/2011/06/wcf-framework-40-monitoring-service.html

WCF IIS-hosted wsHttpBinding service - svcutil generates proxy with basicHttpBinding!

I consider myself pretty expert at WCF but this has me stumped. I don't know if this is a .NET Framework 4/WCF 4 thing with it's automatic configuration or what but I am getting strange behavior. I basically have a WCF 4 WCF service hosted in IIS project. It all worked and then I went in and switched the config from basicHttpBinding to wsHttpBinding. I tried to Update the Service Reference in my consuming app and I get basicHttpBinding output in the generated config. So, of course, I dropped down and ran svcutil.exe aggainst the .svc file and same results. This is the config file (Blah substituted for name that I can't use in public):
<system.web>
<compilation debug="true" targetFramework="4.0" />
<authentication mode="Windows"></authentication>
<identity impersonate="true"/>
</system.web>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpEndpointBinding">
<security mode="Message">
<message clientCredentialType="Windows" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="Blah.Services.RONScheduler.BlahService.BlahDataServiceBehavior"
name="Blah.Services.RONScheduler.FAMService">
<endpoint address="BlahDataService" binding="wsHttpBinding" bindingConfiguration="WSHttpEndpointBinding"
name="WSHttpEndpoint" contract="Blah.Services.RONScheduler.FAMService.IBlahDataService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="Blah.Services.RONScheduler.BlahService.BlahDataServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
<behavior name="">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
This is what I get generated out before I clean out the unncessary stuff:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IBlahDataService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/BlahService/BlahDataService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IBlahDataService"
contract="IBlahDataService" name="BasicHttpBinding_IBlahDataService" />
</client>
</system.serviceModel>
As you can see it's as if it's ignoring the wsHttpBinding setting in the config. What gives?
Have you checked your default protocol bindings, a new feature in WCF 4 ??
By default, they're in your machine.config, and should look like this:
<system.serviceModel>
<protocolMapping>
<add scheme="http" binding="basicHttpBinding" bindingConfiguration="" />
<add scheme="net.tcp" binding="netTcpBinding" bindingConfiguration=""/>
<add scheme="net.pipe" binding="netNamedPipeBinding" bindingConfiguration=""/>
<add scheme="net.msmq" binding="netMsmqBinding" bindingConfiguration=""/>
</protocolMapping>
So this kinda implies to me that if you're hitting a HTTP address, WCF 4 will use basicHttpBinding by default.
You can change those bindings in your own configs, if needed.
Found this in A Developer's Introduction to Windows Communication Foundation 4
Given the configurations you provided, my guess would be that the service name is invalid and the host falls back to default configuration.
Make sure the service name matches the implementation class name.
I came to this conclusion because the interface name is Blah.Services.RONScheduler.FAMService.IBlahDataService and the class name is Blah.Services.RONScheduler.FAMService. It looks like there is something missing after FAMService.

File upload using WCF service not working when transferMode="Streamed"

Configuration details are as follows:
Web.config of Wcf service which is hosted.
<basicHttpBinding>
<binding name="HttpBinding_MTOM" messageEncoding="Mtom"
transferMode="Streamed" maxBufferSize="65536"
maxReceivedMessageSize="534773760">
<security mode="None">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
<services>
<service name="OA.Smart.Services.FileTransferService"
behaviorConfiguration="FileTransferServiceBehavior">
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="HttpBinding_MTOM"
contract="OA.Smart.ServiceContract.IFileTransferService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behavior name="FileTransferServiceBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
I have a smart client application which accesses this WCF service.App.Config is as follows
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IFileTransferService"
closeTimeout="00:30:00" openTimeout="00:30:
receiveTimeout="00:30:00" sendTimeout="00:30:00"
allowCookies="false" bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536"
messageEncoding="Mtom" textEncoding="utf-8"
transferMode="Streamed" useDefaultWebProxy="true">
<readerQuotas
maxDepth="32" maxStringContentLength="8192"
maxArrayLength="16384" maxBytesPerRead="4096"
maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint
address="http://localhost:4149/OA.Smart.ServiceHost/FileTransferService.svc"
behaviorConfiguration="defaultServiceBehaviour"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IFileTransferService"
contract="FileTransferServiceReference.IFileTransferService"
name="BasicHttpBinding_IFileTransferService">
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="defaultServiceBehaviour">
<dataContractSerializer maxItemsInObjectGraph="2147483646" />
</behavior>
</endpointBehaviors>
</behaviors>
With this configuration in place whenever i try to upload my file,It throws as error
System.Net.WebException: The remote server returned an error: (400) Bad Request.
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.
HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)}
However if i change transferMode="Streamed" to "Buffered" it works as expected. I do not understand why it behaves this way. TransferMode of WCF service is streamed, so it should work with streamed.
Please tell me how to make it work with transferMode="Streamed"
Problem was with hosting WCF services.I had hosted them on Cassini(Web server which ships with VS2008) instead of IIS.Cassini does not allow streaming over HTTP.So just using IIS to host WCF services resolved this issue.
You only want to upload files to the server? In that case, have you tried using
transferMode="StreamedRequest"
instead of "Streamed" ?? Any difference?
Also, can you show us the service contract (the interface you're programming against) ?? That might also gives us a clue.
Marc