I have a WCF service that is used to generate reports. That part works fine, but we need to archive the reports after being converted to PDF and that means sending the PDF to another WCF service.
Occasionally I get this error: "The remote server returned an unexpected response: (400) Bad Request."
I suspect that perhaps the data being sent to the service is too big. In this case, I'm sending an object that represents a file. It contains a property which is a byte array (and in this case it is 147800 bytes) and a few other properties (such as file
name).
I am using the WCF test client to test this. We also have a web application that's requesting the report with the same parameters and it is failing too, so I am pretty sure it isn't anything with the WCF Test Client configuration.
I can create the client for the second service, and when I call the method the exception occurs:
using (DocumentStorageServiceClient client = new DocumentStorageServiceClient())
{
long documentID = client.StoreReportDocument(document); // exception occurs here
}
I have tried tweaking the configuration for both the client settings on the first service and the service settings on the second service. Both services are behind a firewall so I don't think any security settings are coming into play here.
I had wanted to limit the request size to 10 MB but we may need to raise that at some point.
Here are the configuration settings for the first (reporting) service (which works fine):
If there are any typos in the endpoint addresses or contract names, it's probaby because I removed our real values from for this post.
I notice that there is no binding configuration on the second (document storage) service's web.config for the service itself. I assume it's using the defaults. I had added a binding configuration and adjusted some of the values but that isn't working.
I have also tried adjusting the httpRuntime's maxRequestSize and that didn't make a difference either.
At this point, I am not sure if I am looking in the right place. I need to get this resolved ASAP as I have a dealine to meet. Please help.
Why don't you copy the binding configuration from the first to the second service? The default timeout values, which are used for the second service if I understand you correctly, may not suffice.
I've already upped the values in both web.configs to the following. I know the values may not be the most appropriate but at least I am not getting the bad request error anymore.
After making the changes to the service host web.config, I updated my service reference in the client. Now, when I run it, I no longer get the bad request error, I get this:
The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter MyCompany.DocumentStorageServices:document. The InnerException message was 'There was an error deserializing the object of
type MyCompany.DocumentStorage.ReportDocument. 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. Line 1, position 63752.'. Please see InnerException for more details.
Server stack trace:
at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
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)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at INoticeService.GetNoticePdf(NoticeRequestParams noticeRequestParams, Boolean applyWatermark)
at NoticeServiceClient.GetNoticePdf(NoticeRequestParams noticeRequestParams, Boolean applyWatermark)
I don't know where the MaxArrayLength quota of 16384 is coming from. It isn't in either web.config so is there a default value somewhere that's being used or am I missing something else?
Try to set the maxArrayLength to 2147483647, which is the max of an Int32. You may also want to increase the value for the maxReceivedMessageSize and maxBufferSize.
1. Is it even necessary to specify a binding configuration for the service (such as specifying maxReceivedMessageSize, etc.) or is that for the client only? When I created my .svc in my service project it created the services/service/endpoint section for
me but there was no binding section. When I added a service reference in the client application, it created a bindings/basicHttpBinding/binding section for the service it will be calling as well as a client/endpoint section.
2. If I update my service reference and then look at the .svcinfo file I see that the maxReceivedMessageSize is 65536. If I specify a binding configuration on the service and set a higher value (and set to a different higher value on the client as well,
just for kicks), refreshing the service reference doesn't change this value. Therefore, can I safely assume that the value in the .svcinfo file is in no way related to the values in either of the configuration files? If so, should I be concerned with the
values in the .svcinfo file? Before I got the Bad request error again, I was getting messages saying that the maximum array length quota was 16384 and that value had been exceeded when reading XML data. I searched for that value in my solution and the only
place I found it was in the .svcinfo file. Where is this value coming from?
Simply put, I want to be able to upload "document" objects with a maximum size of 4 MB. What settings do I need in the server and the client to allow this?
First, you can also turn on the WCF service tracing at server-side and collect some trace log to see the detailed error it logged and verify if the message size(or related quota limit) does be the cause of the problem.
For WCF service which need to accept large size data(in request message), there are several settings you need to take care:
* the maxReceivedMessageSize and other related attributes in the <binding> element. And yes, you need to specify the <binding> through "bindingConfiguration" attribute for both your service and client. And the <binding> setting at client
and service sides need to match.
* the <readerQuotas> setting (under <binding> element) which can specify some limitation of the underlying data reader(for processing underlying WCF messsages). e.g.
* the "maxItemsInObjectGraph" attribute in <dataContractSerializer> element. This one is for controlling the underlying DataContractSerializer in case your service will transfer complicated large data object. You can specify it under servicebehavior
element.
* and the <httpRuntime> element which contains the maxRequestLength and executionTimeout attributes. This is necessary when you host your WCF http based service in ASP.NET/IIS environment.
For test purpose, you can set them to the max integer value as other members have suggested. I agree that sometimes such issue is really painful to troubleshoot, but you can try creating a simplified repro and then apply the above settings one by one to
hit the point.
I turned on tracing yesterday and it said that "No matching <service> tag was found. Default endpoints added."
That seemed to match what I was seeing because the defaults were being used instead of my settings. As it turns out, on the service host I was specifying a binding with a name and then associating that with the endpoint by setting the bindingConfiguration
to the same name. After searching the web, I found a post somewhere that said not to use a name and I tried that, first using a simple service/console app where I could replicate it. I tried it and it worked. I then made similar changes to my real application
and I got it working.
I have another application that is connecting to my service and it is also getting the 400 Bad Request error. I turned tracing on at the service and I see the following:
No matching <service> tag was found. Default endpoints added.
The ServiceDebugBehavior Help Page is enabled at a relative address and cannot be created because there is no base address.
The maximum message size quota for incoming messages (1048576) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element.
Should I be concerned about the first two messages?
As for the third, the "document" is over 3 MB but it contains XML so with the Base64 encoding it may be exceeding the limit I set so I have bumped it to 15728640.
desertfoxaz
Member
307 Points
358 Posts
The remote server returned an unexpected response: (400) Bad Request.
Apr 06, 2012 03:53 PM|LINK
I have a WCF service that is used to generate reports. That part works fine, but we need to archive the reports after being converted to PDF and that means sending the PDF to another WCF service.
Occasionally I get this error: "The remote server returned an unexpected response: (400) Bad Request."
I suspect that perhaps the data being sent to the service is too big. In this case, I'm sending an object that represents a file. It contains a property which is a byte array (and in this case it is 147800 bytes) and a few other properties (such as file name).
I am using the WCF test client to test this. We also have a web application that's requesting the report with the same parameters and it is failing too, so I am pretty sure it isn't anything with the WCF Test Client configuration.
I can create the client for the second service, and when I call the method the exception occurs:
using (DocumentStorageServiceClient client = new DocumentStorageServiceClient()) { long documentID = client.StoreReportDocument(document); // exception occurs here }I have tried tweaking the configuration for both the client settings on the first service and the service settings on the second service. Both services are behind a firewall so I don't think any security settings are coming into play here.
I had wanted to limit the request size to 10 MB but we may need to raise that at some point.
Here are the configuration settings for the first (reporting) service (which works fine):
Here are the configuration settings for the second service. The breakpoint I set at the method on the service side is never hit.
If there are any typos in the endpoint addresses or contract names, it's probaby because I removed our real values from for this post.
I notice that there is no binding configuration on the second (document storage) service's web.config for the service itself. I assume it's using the defaults. I had added a binding configuration and adjusted some of the values but that isn't working. I have also tried adjusting the httpRuntime's maxRequestSize and that didn't make a difference either.
At this point, I am not sure if I am looking in the right place. I need to get this resolved ASAP as I have a dealine to meet. Please help.
mm10
Contributor
6409 Points
1184 Posts
Re: The remote server returned an unexpected response: (400) Bad Request.
Apr 06, 2012 05:37 PM|LINK
Why don't you copy the binding configuration from the first to the second service? The default timeout values, which are used for the second service if I understand you correctly, may not suffice.
desertfoxaz
Member
307 Points
358 Posts
Re: The remote server returned an unexpected response: (400) Bad Request.
Apr 06, 2012 06:55 PM|LINK
I've already upped the values in both web.configs to the following. I know the values may not be the most appropriate but at least I am not getting the bad request error anymore.
The service host web.config:
The client web.config:
After making the changes to the service host web.config, I updated my service reference in the client. Now, when I run it, I no longer get the bad request error, I get this:
The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter MyCompany.DocumentStorageServices:document. The InnerException message was 'There was an error deserializing the object of type MyCompany.DocumentStorage.ReportDocument. 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. Line 1, position 63752.'. Please see InnerException for more details.
Server stack trace:
at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
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)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at INoticeService.GetNoticePdf(NoticeRequestParams noticeRequestParams, Boolean applyWatermark)
at NoticeServiceClient.GetNoticePdf(NoticeRequestParams noticeRequestParams, Boolean applyWatermark)
I don't know where the MaxArrayLength quota of 16384 is coming from. It isn't in either web.config so is there a default value somewhere that's being used or am I missing something else?
mm10
Contributor
6409 Points
1184 Posts
Re: The remote server returned an unexpected response: (400) Bad Request.
Apr 06, 2012 10:03 PM|LINK
Try to set the maxArrayLength to 2147483647, which is the max of an Int32. You may also want to increase the value for the maxReceivedMessageSize and maxBufferSize.
desertfoxaz
Member
307 Points
358 Posts
Re: The remote server returned an unexpected response: (400) Bad Request.
Apr 06, 2012 10:19 PM|LINK
I don't know what I did but I am back to the Bad Request exception again. I tried your recommendations and it didn't change anything.
desertfoxaz
Member
307 Points
358 Posts
Re: The remote server returned an unexpected response: (400) Bad Request.
Apr 06, 2012 11:14 PM|LINK
Two questions:
1. Is it even necessary to specify a binding configuration for the service (such as specifying maxReceivedMessageSize, etc.) or is that for the client only? When I created my .svc in my service project it created the services/service/endpoint section for me but there was no binding section. When I added a service reference in the client application, it created a bindings/basicHttpBinding/binding section for the service it will be calling as well as a client/endpoint section.
2. If I update my service reference and then look at the .svcinfo file I see that the maxReceivedMessageSize is 65536. If I specify a binding configuration on the service and set a higher value (and set to a different higher value on the client as well, just for kicks), refreshing the service reference doesn't change this value. Therefore, can I safely assume that the value in the .svcinfo file is in no way related to the values in either of the configuration files? If so, should I be concerned with the values in the .svcinfo file? Before I got the Bad request error again, I was getting messages saying that the maximum array length quota was 16384 and that value had been exceeded when reading XML data. I searched for that value in my solution and the only place I found it was in the .svcinfo file. Where is this value coming from?
desertfoxaz
Member
307 Points
358 Posts
Re: The remote server returned an unexpected response: (400) Bad Request.
Apr 06, 2012 11:30 PM|LINK
Simply put, I want to be able to upload "document" objects with a maximum size of 4 MB. What settings do I need in the server and the client to allow this?
Steven Cheng...
Contributor
4199 Points
548 Posts
Microsoft
Moderator
Re: The remote server returned an unexpected response: (400) Bad Request.
Apr 10, 2012 03:04 AM|LINK
Hi desertfoxaz,
First, you can also turn on the WCF service tracing at server-side and collect some trace log to see the detailed error it logged and verify if the message size(or related quota limit) does be the cause of the problem.
#Service Trace Viewer Tool (SvcTraceViewer.exe)
http://msdn.microsoft.com/en-us/library/ms732023.aspx
#Tracing
http://msdn.microsoft.com/en-us/library/ms730342.aspx
For WCF service which need to accept large size data(in request message), there are several settings you need to take care:
* the maxReceivedMessageSize and other related attributes in the <binding> element. And yes, you need to specify the <binding> through "bindingConfiguration" attribute for both your service and client. And the <binding> setting at client and service sides need to match.
* the <readerQuotas> setting (under <binding> element) which can specify some limitation of the underlying data reader(for processing underlying WCF messsages). e.g.
<basicHttpBinding> <binding name="xxx" maxBufferSize="10000000" maxBufferPoolSize="10000000" maxReceivedMessageSize="10000000"> <readerQuotas maxDepth="10000000" maxStringContentLength="10000000" maxArrayLength="10000000" maxBytesPerRead="10000000" maxNameTableCharCount="10000000" /> </binding>
* the "maxItemsInObjectGraph" attribute in <dataContractSerializer> element. This one is for controlling the underlying DataContractSerializer in case your service will transfer complicated large data object. You can specify it under servicebehavior element.
#DataContractSerializer.MaxItemsInObjectGraph Property http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.maxitemsinobjectgraph.aspx
e.g.
<behaviors> <serviceBehaviors> <behavior name="Umea.se.EventReactor.ServiceTier.ServiceViewEventBehavior"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> <dataContractSerializer maxItemsInObjectGraph="2147483647" /> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
* and the <httpRuntime> element which contains the maxRequestLength and executionTimeout attributes. This is necessary when you host your WCF http based service in ASP.NET/IIS environment.
For test purpose, you can set them to the max integer value as other members have suggested. I agree that sometimes such issue is really painful to troubleshoot, but you can try creating a simplified repro and then apply the above settings one by one to hit the point.
Feedback to us
Microsoft One Code Framework
desertfoxaz
Member
307 Points
358 Posts
Re: The remote server returned an unexpected response: (400) Bad Request.
Apr 10, 2012 05:30 PM|LINK
I turned on tracing yesterday and it said that "No matching <service> tag was found. Default endpoints added."
That seemed to match what I was seeing because the defaults were being used instead of my settings. As it turns out, on the service host I was specifying a binding with a name and then associating that with the endpoint by setting the bindingConfiguration to the same name. After searching the web, I found a post somewhere that said not to use a name and I tried that, first using a simple service/console app where I could replicate it. I tried it and it worked. I then made similar changes to my real application and I got it working.
desertfoxaz
Member
307 Points
358 Posts
Re: The remote server returned an unexpected response: (400) Bad Request.
Apr 10, 2012 06:53 PM|LINK
I have another application that is connecting to my service and it is also getting the 400 Bad Request error. I turned tracing on at the service and I see the following:
Should I be concerned about the first two messages?
As for the third, the "document" is over 3 MB but it contains XML so with the Base64 encoding it may be exceeding the limit I set so I have bumped it to 15728640.