Asked  7 Months ago    Answers:  5   Viewed   36 times

I've written a WCF service with .NET 4.0, which is hosted on my Windows 7 x64 Ultimate system with IIS 7.5. One of the service methods has an 'object' as argument and I'm trying to send a byte[] which contains a picture. As long as the file size of this picture is less then approx. 48KB, all goes well. But if I'm trying to upload a larger picture, the WCF service returns an error: (413) Request Entity Too Large. So ofcourse I've spent 3 hours Googling the error message and every topic I've seen about this subject suggests raising the 'uploadReadAheadSize' property. So what I've done is using the following commands (10485760 = 10MB):

"appcmd.exe set config -section:system.webserver/serverruntime/uploadreadaheadsize: 10485760 /commit:apphost"

"cscript adsutil.vbs set w3svc/<APP_ID>/uploadreadaheadsize 10485760"

I've also used IIS Manager to set the value by opening the site and going to "Configuration Editor" under Management. Unfortunately I'm still getting the Request Entity Too Large error and it's getting really frustrating!

So does anybody know what else I can try to fix this error?

 Answers

85

That is not problem of IIS but the problem of WCF. WCF by default limits messages to 65KB to avoid denial of service attack with large messages. Also if you don't use MTOM it sends byte[] to base64 encoded string (33% increase in size) => 48KB * 1,33 = 64KB

To solve this issue you must reconfigure your service to accept larger messages. This issue previously fired 400 Bad Request error but in newer version WCF started to use 413 which is correct status code for this type of error.

You need to set maxReceivedMessageSize in your binding. You can also need to set readerQuotas.

<system.serviceModel>
  <bindings>
    <basicHttpBinding>
      <binding maxReceivedMessageSize="10485760">
        <readerQuotas ... />
      </binding>
    </basicHttpBinding>
  </bindings>  
</system.serviceModel>
Tuesday, June 1, 2021
 
Niels
answered 7 Months ago
25

As Matt Burland suggested, you need to configure the service end as well as the client. See Configuring Services Using Configuration Files for details. The task is not much different from what you have done on the client end of the wire. Here's an excerpt from the aforementioned article.

WCF uses the System.Configuration configuration system of the .NET Framework. When configuring a service in Visual Studio, use either a Web.config file or an App.config file to specify the settings. The choice of the configuration file name is determined by the hosting environment you choose for the service. If you are using IIS to host your service, use a Web.config file. If you are using any other hosting environment, use an App.config file.

I would suggest not setting everything to int.MaxValue as have a MaxReceivedMessageSize set to 2GB opens you up to DOS (Denial-Of-Service) attacks and the like. The remarks section of the MaxReceivedMessageSize property even states:

The size of the messages that can be received on the wire by services using the WSHttpBindingBase is bounded by the amount of memory allocated for each message. This bound on message size is intended to limit exposure to denial of service (DoS) attacks.

You might just be trying to get it to work at this point, but it is far from recommended to leave it this way.

Friday, July 30, 2021
 
eek
answered 5 Months ago
eek
69

You need to use the /upload "media upload" path to upload anything over a few MB. The URL and POST format are slightly different:

You'd do:

  1. POST https://www.googleapis.com/upload/gmail/v1/users/userId/drafts
  2. add a HTTP header like "Content-type: multipart/related; boundary="part_boundary""
  3. POST body looks more like:
--part_boundary
Content-Type: application/json; charset=UTF-8

{
}

--part_boundary
Content-Type: message/rfc822

From: script@example.org
To: user@example.com
Subject: test

body here

--part_boundary--

See this for more info (which then links to this).

Saturday, July 31, 2021
 
abyss.7
answered 4 Months ago
21

Make sure you have enabled the Application Server role.

Wednesday, September 1, 2021
 
Pratik
answered 3 Months ago
76

To my knowledge, and I have been doing extensive work with WCF in the last month, you can not share the same exact URI for more than one endpoint. In WCF, a "service" is not defined by the implementation of a contract, but by the contract itself (which also follows WSDL and standard SOA practices.) Endpoints allow you to expose a single service via multiple protocols (and therefor different addresses), but you can not share different services on the same exact address. Logically that wouldn't work.

Assume the following scenario (which is what you are trying to accomplish):

IProductService exposed @ http://localhost/service
ICategoryService exposed @ http://localhost/service
IMetadataExchange exposed @ http://localhost/service/mex

It is easy enough to access the MEX endpoint...it has a unique URI. However, how do you access either of IProductService or ICategoryService? There is nothing that allows you to differentiate the two other than a URI. WCF has nothing that will allow it to route between messages that are supposed to go to IProductservice, and those that are supposed to go to ICategoryService. Since both use the same URI, you do indeed have a conflict. Every service CONTRACT must be exposed via a unique URI. Every endpoint that utilizes the same exact binding must use a distinct address.

There is a way to achieve what you need. The problem is message routing. WCF does not natively support message routing OOB, however it does provide the ability to implement your own message router. (Or, if you are willing to use beta tech, .NET 4.0 comes with a message router out of the box, based on the articles linked below, but with improved configurability.) Michele Bustamante, a veritable sorceress of WCF, has provided a complete implementation and article describing message routing at the following links:

http://msdn.microsoft.com/en-us/magazine/cc500646.aspx http://msdn.microsoft.com/en-us/magazine/cc546553.aspx

The general idea is that you set up a single service that listens on a single URI. This service uses wildcard dispatch to a single service operation, which then determines which unique URI to route each message to. You can make the determination any way you wish, however the simplest is via the request Action, assuming each action on your two interfaces, IProductService and ICategoryService, are globally unique. You will end up with more services, however...the router itself is a distinct WCF service that would need to be hosted just like any other.

Tuesday, September 28, 2021
 
ttran4040
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share