ASP.NET MVC – Multiple Files Upload Bug or by-design issue?
Update: Yes. Kiran confirmed that it’s by design.
This is by design. This is part of System.Web and so we are not too inclined to fix this issue currently. A similar related issue was filed against Web API. You can check the resolution information on it. MultipartFormDataStreamProvider is creating a blank file even though the multipart form-data request isn’t sending one
Thanks,
Kiran
The issue is that when you http-post the request that contains a file html element then you got 1 for files.Count() but null for files.First().
One of my ex-colleagues faced this issue. He shared me this stackoverflow question posted by someone who is having a similar issue.
Here is the code for replicating the issue. (I will upload the sample to my blog’s git repository later.)
View
|
|
Controller
|
|
Screenshots
Steps to replicate the issue
- Run the program
- Click on “Upload” without selecting any file.
- Check the value of “files” enumerable. You will see 1 for files.Count() and null for files.First().
Ok. I am not sure whether this is the bug or by-design issue so I posted the questions in MVC codeplex forum.
Request.Files
While I am waiting the reply from MVC team, I did a few experiments on this. The first thing that I did is to use Request.Files instead of binder so I changed the code as below.
|
|
Here is what I got. I believe that MVC code is also using Request.Files in binder to do the transformation from raw request to object. The count for Request.Files is also 1 even we don’t even select any file.
As the Request.Files has a similar logic, I captured the raw http request in fidder and here is what I found.
POST http://localhost:17002/Home/Upload HTTP/1.1 Accept: text/html, application/xhtml+xml, */* Referer: http://localhost:17002/ Accept-Language: en-US User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; MALC; rv:11.0) like Gecko Content-Type: multipart/form-data; boundary=—————————7de1d0220fe6 Accept-Encoding: gzip, deflate Connection: Keep-Alive Content-Length: 191 DNT: 1 Host: localhost:17002 Pragma: no-cache
—————————–7de1d0220fe6 Content-Disposition: form-data; name=“files”; filename="" Content-Type: application/octet-stream —————————–7de1d0220fe6–
You see, there is one empty item “filename=""” in form-data when we submit the request without selecting the file. This might be the reason why Request.Files is returning the count 1 instead of 0.
Request.Files (“file”) Vs HttpPostedFileBase (null)
Why do we got null for first index of “Files” enumerable?
HttpFileCollectionValueProvider.GetHttpPostedFileDictionary method create the directory based on http file request. HttpPostedFileBaseModelBinder.ChooseFileOrNull returns null value for filename="". HttpFileCollectionValueProvider added that value to directory without checking the null value so I think it might be a by-design issue.
Here is the test code that shows null value.
|
|
That’s all that I have tested.
If you are interested in this issue, you can probably check the following methods below.
- HttpFileCollectionValueProvider.GetHttpPostedFileDictionary
- HttpPostedFileBaseModelBinder.ChooseFileOrNull
I will update this blog post when I get any reply from MVC team.