- Home
- LLBLGen Pro
- Bugs & Issues
Increasing Size Limit with WCF
I am using WCF to save Entities through a Web Service. Trying to save a screenshot as a byte[] into an entity, but keeps returning " The remote server returned an unexpected response: (413) Request Entity Too Large."
I've tried increasing the size limit by editing the maxRequestLength, MaxBufferSize, MaxRecievedMessageSize all to 2147483647 with no change in actual limit.
Not all that familiar with Web Services so any help with the proper way to do this is appreciated.
Here's the Error:
System.ServiceModel.ProtocolException: The remote server returned an unexpected response: (413) Request Entity Too Large. ---> System.Net.WebException: The remote server returned an error: (413) Request Entity Too Large.
at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
--- End of inner exception stack trace ---
Server stack trace:
at System.ServiceModel.Channels.HttpChannelUtilities.ValidateRequestReplyResponse(HttpWebRequest request, HttpWebResponse response, HttpChannelFactory`1 factory, WebException responseException, ChannelBinding channelBinding)
at System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)
at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)
at System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout)
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 TPG.Service.ITpgDataService.SaveErrorLogEntity(ErrorLogEntity& entErrorLog)
at TPG.WindowsClient.Program.Application_ThreadException(Object sender, ThreadExceptionEventArgs e) in e:\TPG\TPG.WindowsClient\Program.cs:line 131
Here's the save function
ErrorLogEntity entError = new ErrorLogEntity();
entError.ErrorText = e.Exception.ToString();
entError.ErrorScreenCap = stream.GetBuffer(); //Database Data Type varbinary(MAX)
wcf.dataService.SaveErrorLogEntity(ref entError); //calls to the service via [OperationContract] in an interface project.
public bool SaveErrorLogEntity(ref ErrorLogEntity entity)
{
bool Success = false;
using (DataAccessAdapter adapter = new DataAccessAdapter())
{
Success = adapter.SaveEntity((ErrorLogEntity)entity, true);
}
return Success;
}
Here's the wcf.cs file in the Client to create the connection to the service
class wcf
{
public static TPG.Service.ITpgDataService dataService;
public static void InitialiseWcf(string url)
{
EndpointAddress endpointAddress = new EndpointAddress(url);
//check if we have to make a http or https binding to the webservice
if (url.StartsWith("https"))
{
BasicHttpsBinding basicHttpsBinding = new BasicHttpsBinding();
basicHttpsBinding.Name = "basicHttpsBinding";
basicHttpsBinding.MaxReceivedMessageSize = 2147483647;
basicHttpsBinding.MaxBufferSize = 2147483647;
ChannelFactory<TPG.Service.ITpgDataService> cf = new ChannelFactory<TPG.Service.ITpgDataService>(basicHttpsBinding, endpointAddress);
dataService = cf.CreateChannel();
}
else {
BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
basicHttpBinding.Name = "basicHttpBinding";
basicHttpBinding.MaxReceivedMessageSize = 2147483647;
basicHttpBinding.MaxBufferSize = 2147483647;
//basicHttpBinding.ReaderQuotas.MaxStringContentLength = 2147483647;
ChannelFactory<TPG.Service.ITpgDataService> cf = new ChannelFactory<TPG.Service.ITpgDataService>(basicHttpBinding, endpointAddress);
dataService = cf.CreateChannel();
}
}
}
And here's the full Web.Config in the Web Service Project
<?xml version="1.0"?>
<configuration>
<appSettings>
<add key="ConnectionString.SQL Server (SqlClient)" value="data source=localhost;initial catalog=ThePestGuys;integrated security=SSPI;persist security info=False;packet size=32768;"/> <!--4096-->
</appSettings>
<system.web>
<httpRuntime maxRequestLength="2147483647" useFullyQualifiedRedirectUrl="true" executionTimeout="14400"/>
<compilation debug="true" targetFramework="4.0"/>
<!--<httpRuntime/>-->
</system.web>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="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"/>
<dataContractSerializer maxItemsInObjectGraph="2147483647"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
<add binding="basicHttpBinding" scheme="http"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true"/>
<bindings>
<webHttpBinding >
<binding name="FileTransferServicesBinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647" />
</binding>
</webHttpBinding>
</bindings>
<services/>
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
<security>
<requestFiltering allowDoubleEscaping="true">
<requestLimits maxAllowedContentLength="2147483647"/>
<fileExtensions allowUnlisted="true"/>
<verbs allowUnlisted="true"/>
</requestFiltering>
</security>
<!--
To browse web app root directory during debugging, set the value below to true.
Set to false before deployment to avoid disclosing web app folder information.
-->
<directoryBrowse enabled="true"/>
</system.webServer>
</configuration>
Using: .NET Version 4.0 LLBLGen Pro Version 3.5 Final (Adapter) Microsoft SQL Server 2012 (SQL Server 11.0.2100) Visual Studio 2012
Yes this is a WCF thing. I think maybe you are missing some config values on readerQuotas. Please try something like this:
<basicHttpBinding>
<binding
name="CoreSoapSecure"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:10:00"
sendTimeout="00:01:00"
allowCookies="false"
bypassProxyOnLocal="false"
hostNameComparisonMode="StrongWildcard"
maxBufferSize="524288"
maxBufferPoolSize="524288"
maxReceivedMessageSize="524288"
messageEncoding="Text"
textEncoding="utf-8"
transferMode="Buffered"
useDefaultWebProxy="true">
<readerQuotas
maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
<security mode="Transport">
<transport
clientCredentialType="None"
proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
... investigate the configuration, as it might be not suitable for you. If you specify the configuration in your config, it's not needed to write it again in code. Be sure that you are loading the configuration when using the service.
I've added this using both my own binding name and yours, without the security. Still no luck.
I just tried adding the configuration name when creating the HTTP Binding in the client. Changed it in wcf.cs to this
BasicHttpBinding basicHttpBinding = new BasicHttpBinding("basicHttpBinding");
and instead I get this Error
System.Collections.Generic.KeyNotFoundException was unhandled
HResult=-2146232969
Message=No elements matching the key 'basicHttpBinding' were found in the configuration element collection.
Source=System.ServiceModel
StackTrace:
at System.ServiceModel.Configuration.ServiceModelConfigurationElementCollection`1.get_Item(Object key)
at System.ServiceModel.BasicHttpBinding.ApplyConfiguration(String configurationName)
at System.ServiceModel.BasicHttpBinding..ctor(String configurationName)
at TPG.WindowsClient.wcf.InitialiseWcf(String url) in e:\TPG\TPG.WindowsClient\wcf.cs:line 34
at TPG.WindowsClient.Program.Main() in e:\TPG\TPG.WindowsClient\Program.cs:line 39
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel)
at System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly()
at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData)
at System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext)
at System.Activator.CreateInstance(ActivationContext activationContext)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
There's got to be something not linking up here and I'm getting stumped as to what.
daelmo wrote:
Yes this is a WCF thing. I think maybe you are missing some config values on readerQuotas. Please try something like this:
<basicHttpBinding> <binding name="CoreSoapSecure" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="524288" maxBufferPoolSize="524288" maxReceivedMessageSize="524288" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true"> <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" /> <security mode="Transport"> <transport clientCredentialType="None" proxyCredentialType="None" realm="" /> <message clientCredentialType="UserName" algorithmSuite="Default" /> </security> </binding> </basicHttpBinding>
... investigate the configuration, as it might be not suitable for you. If you specify the configuration in your config, it's not needed to write it again in code. Be sure that you are loading the configuration when using the service.
Joined: 31-Oct-2011
It could be an IIS configuration issue, we had something similar I seem to remember when saving images.
It's discussed here, see the 2nd answer.
http://stackoverflow.com/questions/10122957/iis7-413-request-entity-too-large-uploadreadaheadsize.
It might help.
OK, I've solved the problem! Turns out I didnt have to touch Web.Config after all. Since I was creating the binding settings in the client programmatically it needed all its values set in the object from there before it was used in the service.
So, I added the System.Runtime.Serialization reference to create a new System.Xml.XmlDictionaryReaderQuotas object and added it to basichttpbinding.ReaderQuotas. Edit the values in the new ReaderQuota object and thats it. Nothing else required.
It was as simple as this
BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
XmlDictionaryReaderQuotas reader = new XmlDictionaryReaderQuotas();
basicHttpBinding.MaxBufferSize = 2147483647;
basicHttpBinding.MaxBufferPoolSize = 2147483647;
basicHttpBinding.MaxReceivedMessageSize = 2147483647;
reader.MaxStringContentLength = 2147483647;
reader.MaxDepth = 2147483647;
reader.MaxArrayLength = 2147483647;
reader.MaxBytesPerRead = 2147483647;
reader.MaxNameTableCharCount = 2147483647;
basicHttpBinding.ReaderQuotas = reader;
Thanks for the help, and I hope this will help anybody else creating a config in this way.
I'll Revise that. Needed changes in BOTH client config and server config in the wcf and web.config files. You'll get the same error if you're missing one or the other. Needs to be the same change for both.
Cookie wrote:
OK, I've solved the problem! Turns out I didnt have to touch Web.Config after all. Since I was creating the binding settings in the client programmatically it needed all its values set in the object from there before it was used in the service.
So, I added the System.Runtime.Serialization reference to create a new System.Xml.XmlDictionaryReaderQuotas object and added it to basichttpbinding.ReaderQuotas. Edit the values in the new ReaderQuota object and thats it. Nothing else required.
It was as simple as this
BasicHttpBinding basicHttpBinding = new BasicHttpBinding(); XmlDictionaryReaderQuotas reader = new XmlDictionaryReaderQuotas(); basicHttpBinding.MaxBufferSize = 2147483647; basicHttpBinding.MaxBufferPoolSize = 2147483647; basicHttpBinding.MaxReceivedMessageSize = 2147483647; reader.MaxStringContentLength = 2147483647; reader.MaxDepth = 2147483647; reader.MaxArrayLength = 2147483647; reader.MaxBytesPerRead = 2147483647; reader.MaxNameTableCharCount = 2147483647; basicHttpBinding.ReaderQuotas = reader;
Thanks for the help, and I hope this will help anybody else creating a config in this way.