Insufficient Memory Exception in WCF Large File Uploading - c#

I am trying to upload large files(>10GB) using WCF.
The Service Web.config is as below
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding" maxBufferPoolSize="2147483647000000" maxReceivedMessageSize="2147483647000000" transferMode="Streamed">
<readerQuotas maxDepth="200000000" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:42890/Service1.svc" behaviorConfiguration="endpointBehavior"
binding="basicHttpBinding"
contract="UploadFileService.IService1" name="BasicHttpBinding" />
</client>
And the client side web.config as below
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding" closeTimeout="10:00:00" openTimeout="10:00:00"
receiveTimeout="10:00:00" sendTimeout="10:00:00" maxBufferPoolSize="2147483647000000"
maxReceivedMessageSize="2147483647000000" />
</basicHttpBinding>
</bindings>
I got insufficient memory exception when I run the code, How can I solve it?

In your solution, target x64 instead of Any CPU. This will allow more memory allocation.
However, depending on your solution, you might be able to Stream the file to disk, not requiring to use so much memory.

Related

Message size when calling a WebService (WCF) from desktop application (.Net 2)

I've got a Web Service (WCF) which stores received files in the database.
When I call it from a .NET 4.5 web application I just specify in client's Web.config file:
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_NameOfWS"
maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647" />
</basicHttpBinding>
</bindings>
So the client is allowed to send big files.
When I try to call it from my .NET 2 desktop application (yes, .NET 2) I receive the error:
HTTP 413: Request Entity Too Large
But I've got no Web.config file to configure as it's not a web application.
My app.config looks like:
<applicationSettings>
<NameOfProject.Properties.Settings>
<setting name="NameOfProject_NameOfWebReference_NameOfWS"
serializeAs="String">
<value>http://myURL/NameOfWS.svc</value>
</setting>
</NameOfProject.Properties.Settings>
</applicationSettings>
And the NameOfWS.wsdl file has no maxBufferSize or maxReceivedMessageSize parameter.
Am I missing anything?
Thanks in advance.
For app.config binding configuration example
A few of these methods please try;
<binding name="bindingName" closeTimeout="00:20:00" openTimeout="00:20:00" receiveTimeout="01:00:00" sendTimeout="01:00:00" hostNameComparisonMode="StrongWildcard" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="Transport" />
</binding>
write this on your .net 2 app.config it must be receive file but i suggest you copy .net 4 app.config tag to .net 2 app.config it must work
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding maxReceivedMessageSize="10485760">
<readerQuotas ... />
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
Solved!
If anybody needs to solve an issue like this, I post how I could make it work.
Web.config in my service project:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_MyWCFInterface" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" />
</basicHttpBinding>
</bindings>
<services>
<service name="MyProject.MyWCFClass" >
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_MyWCFInterface"
contract="MyProject.MyWCFInterface"/>
</service>
</services>
</system.serviceModel>
App.config in my client project
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_MyWCFInterface" hostNameComparisonMode="StrongWildcard" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:myPort/MyService.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_MyWCFInterface"
contract="NameOfCreatedService.MyWCFInterface"
name="BasicHttpBinding_MyWCFInterface" />
</client>
</system.serviceModel>
And what I didn't know and have been the final step, is copy this App.config configuration in App.config of the main project of my client's solution, if not the configuration isn't load at the startup and doesn't work the message size configuration.
I hope it can help anybody.
Thanks for the ones who have spent some time with this issue.

WCF webservice over basicHttpBinding with Streaming uses over 2 gigs of ram

I have an IIS hosted WCF webservice, it has two endpoints, one for wsHttpBinding, the other is for basicHttpBinding. I use basicHttpBinding so I can set the transferMode to "Streamed" so I can stream files. This service also is under SSL and needs a client certificate to connect to.
When I call the wsHttpBinding services and everything is fine. When I call the basicHttpBinding services to stream a file it will use all the free ram (the machine has 2.5 gigs) and then hits the page file and throws hard faults. All these hard faults and disk swapping causes the services to time out since it's taking longer than 60 seconds to return.
Below is the function that I am calling that is eating all the ram and timing out
[OperationBehavior]
public Stream GetOrderResults(string clientName, string userName, string password, string institutionId, Guid orderId, string fileName)
{
var fileStream = new System.IO.FileStream(#"\\iwebdev510\Relateprod\TDHub\Temp\TDTestClient\bob.xml", FileMode.Open);
return fileStream;
}
The configuration file for the client calling the webservice looks like this:
<?xml version="1.0"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<system.serviceModel>
<!-- REMOVE THE BEHAVIORS FOR DEV TESTING -->
<behaviors>
<endpointBehaviors>
<behavior name="ClientCertBehavior">
<clientCredentials>
<clientCertificate x509FindType="FindByThumbprint" findValue="8b08c6e6e356a345212e539979fbcaca337aae8a"/>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<!--Dev Endpoints With Certs-->
<endpoint address="https://<obfuscated>/secure/TDHubService.svc"
behaviorConfiguration="ClientCertBehavior"
binding="wsHttpBinding"
bindingConfiguration="wsTDHubServiceBindingTLS"
contract="MortgageCadence.External.TDHub.Protocols.Contracts.Services.ITDHubService" />
<endpoint address="https://<obfuscated>/secure/TDHubFileTransferService.svc"
behaviorConfiguration="ClientCertBehavior"
binding="basicHttpBinding"
bindingConfiguration="basicTDHubFileTransferServiceBindingTLS"
contract="MortgageCadence.External.TDHub.Protocols.Contracts.Services.ITDHubFileTransferService" />
</client>
<bindings>
<basicHttpBinding>
<binding name="basicTDHubFileTransferServiceBinding" maxReceivedMessageSize="2147483647"
transferMode="Streamed">
<readerQuotas maxDepth="64" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None" />
</binding>
<binding name="basicTDHubFileTransferServiceBindingTLS" maxReceivedMessageSize="2147483647"
transferMode="Streamed">
<readerQuotas maxDepth="64" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="Certificate" />
</security>
</binding>
</basicHttpBinding>
<wsHttpBinding>
<binding name="wsTDHubServiceBinding" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="64" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None" />
</binding>
<binding name="wsTDHubServiceBindingTLS" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="64" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="Transport">
<transport clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
I can provide a screen shot of the computers resource monitor being eaten by w3wp.exe, but I can't attach it ATM because my reputation is not high enough.
I have discovered that if I change the transfer mode from "Steamed" to "Buffered" in the binding it completely solves the memory issue, but this appears to be counter to what the documentation suggests. The documentation makes it sound like if you choose "buffered" it will load the entire file into memory before sending, but I've sent a 700 meg file and the memory didn't change in buffered mode.

The maximum string content length quota (8192) has been exceeded.Increase the MaxStringContentLength property on the XmlDictionaryReaderQuotas

I got the following error when i passed an entity object to a WebService
The maximum string content length quota (8192) has been exceeded while reading XML data. This quota may be increased by changing the MaxStringContentLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader
I tried to solve this problem by giving the below code in webconfig of Webservice,but the error still remains. Can anyone Help!!!!!
<bindings>
<wsHttpBinding>
<binding name="MyService" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" />
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
</bindings>
You have to set the maximum string content length quota on the server and the client. So check your client config. If that is not working, check if you are using the right binding.
Your server side Web config allows large strings, but you also need to modify your client side ServiceReferences.ClientConfig file to reflect that.
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="Binding_MyService">
<binaryMessageEncoding />
<httpTransport maxReceivedMessageSize="2147483647" maxBufferSize="2147483647" />
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="yourserviceurlhere"
binding="wsHttpBinding" bindingConfiguration="Binding_MyService"
contract="yourcontracthere" name="MyService" />
</client>
</system.serviceModel>

Error when calling web service with lots of data

I have a WCF service that is hosted locally. My web.config looks like this:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_INavigationService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="6553600" maxBufferPoolSize="5242880" maxReceivedMessageSize="6553600"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/WebServices/NavigationService.svc/"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_INavigationService"
contract="NavigationService.INavigationService" name="BasicHttpBinding_INavigationService" />
</client>
</system.serviceModel>
My service works fine if I pass in less then 8K of text. Anything more and I get the following error:
Sys.WebForms.PageRequestManagerServerErrorException: The formatter threw an exception while trying to deserialize the message: Error in deserializing body of request message for operation 'UpdateSiteMap'. The maximum string content length quota (8192) has been exceeded while reading XML data. This quota may be increased by changing the MaxStringContentLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader. Line 75, position 166
Can someone tell me how to increase the text quota? As you can see, I have it set to maximum integer size.
EDIT
After Tim's suggestion, here is my new Web.Config file:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="6553600" maxBufferPoolSize="5242880" maxReceivedMessageSize="6553600"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/WebServices/NavigationService.svc/"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_INavigationService"
contract="NavigationService.INavigationService" name="BasicHttpBinding_INavigationService" />
</client>
<services>
<service name="Navigation.INavigationService">
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_INavigationService"
contract="NavigationService.INavigationService" />
</service>
</services>
Based on the error message and your description of the issue, you need to ensure that you have the same settings for your service, referencing the same defined binding in the bindingConfig attirbute of the endpoint element:
<system.serviceModel>
<services>
<service name="Navigation.INavigationService">
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_INavigationService"
contract="NavigationService.INavigationService" />
</service>
</services>
</system.serviceModel>
If you're using .NET 4.0 and have not specified the service element, then you are using a default endpoint and default binding (which means your limited to 8192 for maxStringContentLength). The easiest way to overcome this is to remove the name attribute from the binding section of your config - .NET will then use your definition as the default binding. For example:
<binding closeTimeout="00:01:00" ....
Note no name attribute is set.
You may need to use option 1 in this case, or create a similar binding definition with no name, as I'm not 100% sure that default bindings are used for the clients; they definitely are for the service.
See A Developer's Introduction to Windows Communication Foundation 4 for more information on default bindings and endpoints.
Additional Answer Based On Edit
Try this:
<client>
<endpoint address="http://localhost/WebServices/NavigationService.svc/"
binding="basicHttpBinding"
contract="NavigationService.INavigationService"
name="BasicHttpBinding_INavigationService" />
</client>
Delete the <services> section as the default endpoint mechanism for WCF 4.0 will handle that for you, and delete the bindingConfiguration attribute from the client endpoint.

Cannot call WCF WebService from DLL

I'm trying to call a WCF Webservice, from a dll I have made, running inside our CAD Software.
I cannot get it to work though.
When I try to establish my proxy, I get the following error:
Could not find endpoint element with name 'BasicHttpBinding_IAxaptaService' and contract 'AxaptaProxy.IAxaptaService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this name could be found in the client element.
I have searched around abit, and I assume the problem is due to my DLL running inside another program.
There was some articles about copying EndPoint configuration from the app, to the service, but I didn't quite catch, what I was supposed to do.
Anyone have an idea, as to how I can make this work?
The App.Config, created by my client is this:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IAxaptaService" 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:4726/LM/AxaptaService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IAxaptaService"
contract="AxaptaProxy.IAxaptaService" name="BasicHttpBinding_IAxaptaService" />
</client>
</system.serviceModel>
</configuration>
I have tried to merge this into my web.config, on the site that hosts the web-service, as this:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="GetStream.customBinding0">
<binaryMessageEncoding/>
<httpTransport/>
</binding>
</customBinding>
<basicHttpBinding>
<binding name="BasicHttpBinding_IAxaptaService" 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>
<behaviors>
<endpointBehaviors>
<behavior name="AutoCompletionAspNetAjaxBehavior">
<enableWebScript/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
<services>
<service name="AutoCompletion">
<endpoint address="" behaviorConfiguration="AutoCompletionAspNetAjaxBehavior" binding="webHttpBinding" contract="AutoCompletion"/>
</service>
<service name="GetStream">
<endpoint address="" binding="customBinding" bindingConfiguration="GetStream.customBinding0" contract="GetStream"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<client>
<endpoint address="http://localhost:4726/LM/AxaptaService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IAxaptaService"
contract="AxaptaProxy.IAxaptaService" name="BasicHttpBinding_IAxaptaService" />
</client>
</system.serviceModel>
There are a couple of other stuff in there already. I can remove them, if that makes it easier. I've left them in, incase they have some influence on it.
So I tested the service, from a stand-alone winform application, and it works fine.
Could it be because of the App.config? Does my config get loaded, for the .dll?
You'll need to copy the connection information from MyDll.dll.config to Web.config.
Be careful to merge configuration sections rather that simply adding the new data side-by-side, or replacing it. If there are already sections with the same name, you will probably have to combine them.
Here's an article describing the guts of the WCF portions of app.config:
http://msdn.microsoft.com/en-us/library/ms734663.aspx
The main pieces are:
<system.serviceModel>
<bindings>
<!-- various bindings go here... -->
</bindings>
<client>
<!-- endpoints go here... -->
</client>
</system.serviceModel>
You'll need to combine everything within those nodes - add the various types of endpoint elements and the binding elements to your service's web.config.
So, if you have a config that looks like this:
<system.serviceModel>
<bindings>
<someBindingType name="someBinding" />
</bindings>
<client>
<endPoint name="someEndpoint />
</client>
</system.serviceModel>
You'll need to copy over the someBindingType and endPoint elements. The whole element, including ending tags (if there are any), and child elements.
Make sure you don't duplicate system.serviceModel, bindings or client elements. If they're already there, merge into them rather than creating new elements/duplicating.
I finally got it to work!
The problem was, that the app.config does not get loaded, in my .dll project.
To fix this, I created the binding, in code, instead of through the app.config, as mentioned in this thread:
WCF Configuration without a config file
Thank you for all the help though. Merlyn, without your help, I wouldn't even have gotten this far.

Categories