File upload error : "Can not access a closed file"

Reason:

This error occurs partily due to the new memory management feature added in the asp.net2.0 therefore you may wonder same code after migrating from asp.net1.1 to asp.net2.0 starts throwing this error.
As I said,new memory management feature is partily reposible because you may not get this error if you are uploading the file directly without any redirection(due to business requirement) for exp. - storing uploaded file object in the session on file upload page and saving it after user confirmation on the confirmation page.
Most likly you will get this error in the senario I mentioned as an example above subjected to the file size is more than 80Kb. The reason is,according to new memory management feature of asp.net2.0 when you upload a file the input stream is buffered in the memory if its size less than 80Kb otherwise it is stored in the temporary locations on the disk upto 4096Kb so when you maintain an object of any uplaoded file(more than 80Kb size) in session and redirect on different page the current request is disposed and the disk file associated with it is closed as well, now when you try to save uploaded file object on server(using SaveAs method of upload control) from the session, the request processing thread tries to read from the closed file object and thats where you get this error message.But if your uploaded file size is much less than 80Kb then you may not face this error.

Solution:

You can solve this issue by adding following tag in the web.config file of your website.

< httpRuntime maxRequestLength="10240" requestLengthDiskThreshold="4096"/ >

Note - change the values according to your requirement.

maxRequestLength - Specifies the total limit for the input stream buffering threshold, in KB. This limit can be used to prevent denial of service attacks that are caused, for example, by users posting large files to the server.
The default is 4096 KB. If the threshold is exceeded, a ConfigurationErrorsException error is thrown.

requestLengthDiskThreshold- Specifies the limit for the input stream buffering threshold, in kilobytes, it means if size of the stream is more than the value specifed it is stored in the temporary location on the disk otherwise buffered in the memory. This value should not exceed the maxRequestLength attribute.The default is 80 KB.

Note - This attribute is new in the .NET Framework 2.0.

So, if you assign same value to both the attributes, your application process the file upload request just like asp.net1.1.

18 comments:

Anonymous said...

great explanation.

Anonymous said...

Keep posted these to the point solution with great justification.

digish said...

Thanks

JUAN BLANCO said...

thanx.. i will test it right now.

you forget to mention that the instruction

< httpRuntime maxRequestLength="10240" requestLengthDiskThreshold="4096" / >

should be inclosed in the web.config like this..
< configuration >
< system.web >
...
< httpRuntime maxRequestLength="10240" requestLengthDiskThreshold="4096" / >

AnxiousDAD said...

Absolutely wonderfull. Worked on the first try. I have been looking for a resolution for about a month now and this just did the trick.

SuperCal said...

man...what you have is very good...thanks for your info.

keep it up

Anonymous said...

Thanks Sanjay. You saved my day :)

Abhih Kurella said...

That is a wonderful explaination. Thanks for the post.

Cool said...

You saved my evening :)

Anonymous said...

nic way of xplanation...
keep posting...

Syed Imran Rehman said...

Thanx 4 the Great post. It works...

Anonymous said...

Great Post. Thank you!

Anonymous said...

Explanation is really good.

Anonymous said...

Great post, that is very helpful!

Anonymous said...

Very nice article, it solved my Issue.

01011001 said...

Damned ! i have just wasted my whole day on that problem !
Was working in debug on my PC (from VS2010, .NET3.5), but not in release on the server;
I was sure it was a IIS configuration problem.

Thx a lot.

Suncat2000 said...

Thanks for posting your solution. The actual error is "Cannot access a closed file."

Setting the RequestLengthDiskThreshold (to anything, up to MaxRequestSize) in web.config resolves the problem. Apparently ASP.Net buffers the first chunk of the input stream, then treats the stream as closed.

This can happen if you set MaxRequestLength (say, 1536) but let RequestLengthDiskThreshold default. This apparently trips over some internal code, which makes it a Microsoft bug. Setting both values resolves the problem.

Anonymous said...

Awsome!!Greaat job.