The max message size quota for incoming messages (65536) ....To increase the quota, use the MaxReceivedMessageSize property - wcf

I got this crazy problem I'm trying to deal with. I know that when we're getting huge amount of data we must increase the quota on client .config file, but what am I supposed to do if my client is sending huge data "to" the WCF server?
It works perfectly normal when I'm sending small sized input parameter. Unfortunately, it breaks down when the input grows bigger.
Debugger it says:
Bad Request, 400;
on trace file it is:
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.
Is there some way to increase this quota of incomming data on the server side? if so, how?
Here's my sample config related parts:
<bindings>
<basicHttpBinding>
<binding name="MyBasicHttpBinding"
closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00"
sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard" maxBufferSize="2147483647"
maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="64" 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>
<services>
<service name="MyWcfService">
<endpoint address="http://myservice..."
binding="basicHttpBinding" bindingConfiguration="MyBasicHttpBinding"
name="MyBasicHttpBinding" contract="IMyContract" />
</service>
</services>
and here's my client-side code (I create it dynamically):
var binding = new BasicHttpBinding();
binding.MaxBufferPoolSize = 2147483647;
binding.MaxBufferSize = 2147483647;
binding.MaxReceivedMessageSize = 2147483647;
binding.ReaderQuotas.MaxStringContentLength = 2147483647;
binding.ReaderQuotas.MaxArrayLength = 2147483647;
binding.ReaderQuotas.MaxDepth = 2147483647;
binding.ReaderQuotas.MaxBytesPerRead = 2147483647;
var address = new EndpointAddress("http://mylocalservice..");
ChannelFactory<IMyContract> factory = new ChannelFactory<IMyContract>(binding, address);
foreach (OperationDescription op in factory.Endpoint.Contract.Operations)
{
DataContractSerializerOperationBehavior dataContractBehavior =
op.Behaviors.Find<DataContractSerializerOperationBehavior>()
as DataContractSerializerOperationBehavior;
if (dataContractBehavior != null)
{
dataContractBehavior.MaxItemsInObjectGraph = 2147483646;
}
}
public IMyContract MyClientObject = factory.CreateChannel();

You can set the MaxReceivedMessageSize property on the service via the service's config file.
Setting the client's MaxReceivedMessageSize only affects messages received by the client; it has no effect on messages received by the service. Correspondingly, to allow the service to receive large messages, you need to set the service's config file.
Sample Service Config
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="MyBinding" maxReceivedMessageSize="2147483647" />
</wsHttpBinding>
</bindings>
<services>
<service name="MyService">
<endpoint address="http://myservice" binding="wsHttpBinding"
bindingConfiguration="MyBinding" contract="IMyServiceContract" />
</service>
</services>
</system.serviceModel>
The above is a very stripped down config file, but shows the relevant parts. The important part is that you define the binding and give it a name, and set any values explicitly that are different from the defaults, and use that name in the bindingConfiguration attribute on the endpoint element.

My problem was with the wcf test client. For some reason, it wouldn't generate a client config with the increased maxReceivedMessageSize. My fix was to right click "Config file" -> "Edit with SvcConfigEditor" -> bindings -> maxReceivedMessageSize.

This issue can be resolved by adding the below additional binding node to the binding section of config file.
<basicHttpBinding>
<binding maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647"
maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>

Related

WCF - The maximum array length quota (16384)

When I receive files I receive this exception.
My client configuration:
<bindings>
<basicHttpBinding>
<binding name="basicHttpSecuredBinding"
maxReceivedMessageSize = "2147483647" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" sendTimeout="00:25:00" receiveTimeout="00:25:00">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
<security mode="TransportWithMessageCredential">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</basicHttpBinding>
Client endpoint
<client>
<!--TODO: currently configured to work with the staging for testing-->
<endpoint name="ep_SmtkSyncService"
address="https://1234.com/SyncService.svc"
binding="basicHttpBinding"
bindingConfiguration="basicHttpSecuredBinding"
behaviorConfiguration="transportWithClientCredentialsBehavior"
contract="SynerionHcm.Smtk.Domain.Common.Contracts.ISmtkSyncService" />
</client>
This exception has driven me crazy:
The maximum array length quota (16384) has been exceeded while reading XML data. This quota may be increased by changing the MaxArrayLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader.'. Please see InnerException for more details. ---> System.Runtime.Serialization.SerializationException: There was an error deserializing the object of type

Programmatically adding an endpoint

I have a WCF service that I am connecting in client application. I am using following in configuration file.
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="MyNameSpace.TestService" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="2147483647" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" 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:9100/TestService" binding="basicHttpBinding"
bindingConfiguration="MyNameSpace.TestService" contract="TestService.IService" name="MyNameSpace.TestService" />
</client>
</system.serviceModel>
In the code, I am calling API on this service as follows,
TestServiceClient client = new TestServiceClient()
client.BlahBlah()
Now I want to defined endpoint porgramatically. How can that be done? I commented out section from config file as I was thinking I will have to put some code on TestServiceClient instance to add endpoint dynamically but then it throws following exception at the point where TestServiceClient is instantiated.
Could not find default endpoint element that references contract
'TestService.IService' 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
contract could be found in the client element.
How can I accomplish this? Also any point on code examples for adding endpoint programmatically will be appreciated.
To create endpoints and bindings programmatically, you could do this on the service:
ServiceHost _host = new ServiceHost(typeof(TestService), null);
var _basicHttpBinding = new System.ServiceModel.basicHttpBinding();
//Modify your bindings settings if you wish, for example timeout values
_basicHttpBinding.OpenTimeout = new TimeSpan(4, 0, 0);
_basicHttpBinding.CloseTimeout = new TimeSpan(4, 0, 0);
_host.AddServiceEndpoint(_basicHttpBinding, "http://192.168.1.51/TestService.svc");
_host.Open();
You could also define multiple endpoints in your service config, and choose which one to connect to dynamically at run time.
On the client program you would then do this:
basicHttpBinding _binding = new basicHttpBinding();
EndpointAddress _endpoint = new EndpointAddress(new Uri("http://192.168.1.51/TestService.svc"));
TestServiceClient _client = new TestServiceClient(_binding, _endpoint);
_client.BlahBlah();
Can you just use:
TestServiceClient client = new TestServiceClient();
client.Endpoint.Address = new EndPointAddress("http://someurl");
client.BlahBlah();
Note that your binding configuration will no longer apply, as you're not using that endpoint configuration in your configuration file. You'll have to override that, too.
You can try:
TestServiceClient client = new TestServiceClient("MyNameSpace.TestService")
client.BlahBlah()
if not recheck namespace in file TestService is correct?

How do I consume a WS-Security service in WCF over HTTPS?

I'm trying to consume a WS-Security enabled service with WCF. Authentication works using a UsernameToken. I'm not very knowledgeable with WCF web service clients, but I think my configuration below works for regular HTTP communication. I (mostly) used this guide to configure it. The main difference is that I used the VS2010 "Add Service Reference" UI instead of a command prompt.
My problem is that I need to do this over HTTPS. When I use <security mode="Message"> in my app.config, I believe my soap envelope contains the needed WS-Security headers. I can't tell for sure because I can't get logging to work. However, I get the following error: The provided URI scheme 'https' is invalid; expected 'http'. Parameter name: via.
Below are the contents of my app.config file, as well as a sample of my client code.
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="Omitted" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="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" />
<security mode="Message">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" negotiateServiceCredential="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://omitted.com/service" binding="wsHttpBinding" bindingConfiguration="Omitted" contract="Omitted.Omitted" name="Omitted" />
</client>
</system.serviceModel>
var service = new OmittedClient();
service.ClientCredentials.UserName.UserName = "username";
service.ClientCredentials.UserName.Password = "password";
var response = service.DoSomething(new DoSomethingRequest());
Thanks to 500 - Internal Server error for helping me figure it out. Here are the steps I took:
Generate a proxy using Visual Studio/WCF.
Change the security mode to TransportWithmessageCredential.
Use the following code to specify a username/password.
var client = new WebServiceClient();
client.ClientCredentials.UserName.UserName = "USERNAME";
client.ClientCredentials.UserName.Password = "PASSWORD";
If you get a response back, but WCF complains when processing it, there might be a timestamp missing from the response. If that's the case, try this to fix it.
// WCF complains about a missing timestamp (http://www.west-wind.com/weblog/posts/2007/Dec/09/Tracing-WCF-Messages)
var elements = service.Endpoint.Binding.CreateBindingElements();
elements.Find().IncludeTimestamp = false;
service.Endpoint.Binding = new CustomBinding(elements);

WCF- Duplex connection (hosted in IIS)

I have a full duplex, I run successfully in my local machine.
I host it in my server (IIS - server 2008 R2-STANDARD), and trying to connect, as following:
this.myCallbackProxy = new MyCallbackProxy();
InstanceContext cntx = new InstanceContext(myCallbackProxy);
this.Proxy = new MyServiceClientProxy(cntx, "WSDualHttpBinding_I_BridgeWCFService");
this.Proxy.ClientCredentials.Windows.ClientCredential.UserName = "YY";
this.Proxy.ClientCredentials.Windows.ClientCredential.Password = "PP";
Now, when I try to call an API, I stuck until time out.
I tried to configure the WCF in the IIS to connect as specific user , but then when I try to call an API from my client, I get the following exception:
"The content type text/html; charset=utf-8 of the response message does not match the content type of the binding (application/soap+xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 1024 bytes of the response"
I must mention that I have another WCF hosted in same IIS, with same user (server user name), and it works perfect. (I create another (similar) application poll for the duplex WCF)
My config file:
<bindings>
<wsDualHttpBinding>
<binding name="WSDualHttpBinding_I_BridgeWCFService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="2147483646" maxReceivedMessageSize="2147483646"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="2147483646"
maxArrayLength="2147483646" maxBytesPerRead="2147483646" maxNameTableCharCount="2147483646" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"/>
<security mode="None">
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</wsDualHttpBinding>
</bindings>
<client>
<endpoint address="http://xx.xx.xx.xx/_Bridge/_BridgeWcfService.svc"
binding="wsDualHttpBinding"
bindingConfiguration="WSDualHttpBinding_I_BridgeWCFService"
contract="_BridgeWcfServiceReference.I_BridgeWCFService"
name="WSDualHttpBinding_I_BridgeWCFService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
</client>

The maximum message size quota for incoming messages (65536) has been exceeded

I get this exception while creating scope for few tables all those tables are huge in design
<bindings>
<wsHttpBinding>
<binding name="wsHttpBinding_ISyncServices" closeTimeout="00:10:00"
openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows"
proxyCredentialType="None" realm="">
<extendedProtectionPolicy policyEnforcement="Never" />
</transport>
<message clientCredentialType="Windows"
negotiateServiceCredential="true" algorithmSuite="Default" />
</security>
</binding>
</wsHttpBinding>
</bindings>
I have made MaxReceivedMessageSize to 2147483647
but still it is giving me below exception at this line
client.GetTableDescription(scopeName, syncTable)
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.
As per this question's answer
You will want something like this:
<bindings>
<basicHttpBinding>
<binding name="basicHttp" allowCookies="true"
maxReceivedMessageSize="20000000"
maxBufferSize="20000000"
maxBufferPoolSize="20000000">
<readerQuotas maxDepth="32"
maxArrayLength="200000000"
maxStringContentLength="200000000"/>
</binding>
</basicHttpBinding> </bindings>
Please also read comments to the accepted answer there, those contain valuable input.
If you are using CustomBinding then you would rather need to make changes in httptransport element.
Set it as
<customBinding>
<binding ...>
...
<httpsTransport maxReceivedMessageSize="2147483647"/>
</binding>
</customBinding>
Updating the config didn't work for me, but I was able to edit the binding programmatically:
private YourAPIClient GetClient()
{
Uri baseAddress = new Uri(APIURL);
var binding = new BasicHttpBinding();
binding.MaxReceivedMessageSize = 20000000;
binding.MaxBufferSize = 20000000;
binding.MaxBufferPoolSize = 20000000;
binding.AllowCookies = true;
var readerQuotas = new XmlDictionaryReaderQuotas();
readerQuotas.MaxArrayLength = 20000000;
readerQuotas.MaxStringContentLength = 20000000;
readerQuotas.MaxDepth = 32;
binding.ReaderQuotas = readerQuotas;
if (baseAddress.Scheme.ToLower() == "https")
binding.Security.Mode = BasicHttpSecurityMode.Transport;
var client = new YourAPIClient(binding, new EndpointAddress(baseAddress));
return client;
}
You need to make the changes in the binding configuration (in the app.config file) on the SERVER and the CLIENT, or it will not take effect.
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding maxReceivedMessageSize="2147483647 " max...=... />
</basicHttpBinding>
</bindings>
</system.serviceModel>
You also need to increase maxBufferSize. Also note that you might need to increase the readerQuotas.
This worked for me:
Dim binding As New WebHttpBinding(WebHttpSecurityMode.Transport)
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None
binding.MaxBufferSize = Integer.MaxValue
binding.MaxReceivedMessageSize = Integer.MaxValue
binding.MaxBufferPoolSize = Integer.MaxValue
For me, the settings in web.config / app.config were ignored. I ended up creating my binding manually, which solved the issue for me:
var httpBinding = new BasicHttpBinding()
{
MaxBufferPoolSize = Int32.MaxValue,
MaxBufferSize = Int32.MaxValue,
MaxReceivedMessageSize = Int32.MaxValue,
ReaderQuotas = new XmlDictionaryReaderQuotas()
{
MaxArrayLength = 200000000,
MaxDepth = 32,
MaxStringContentLength = 200000000
}
};
My solution was to use the "-OutBuffer 2147483647" parameter in my query, which is part of the Common Parameters.
PS C:> Get-Help about_CommonParameters -Full