I'm attempting upload multiple files in ASP.NET MVC and I have this simple foreach loop in my controller
foreach (HttpPostedFileBase f in Request.Files)
{
if (f.ContentLength > 0)
FileUpload(f);
}
The previous code generates this error:
Unable to cast object of type 'System.String' to type 'System.Web.HttpPostedFile'.
What I don't understand is why Request.Files[1] returns an HttpPostedFileBase but when it's iterated over, it returns strings (presumably the file names).
Note: I know this can be solved with a for loop. Also, I tried using HttpPostedFile, with the same error.
The enumerator on the
HttpFileCollection
returns the keys (names) of the files, not theHttpPostedFileBase
objects. Once you get the key, use theItem
([]
) property with the key (filename) to get theHttpPostedFileBase
object.The following code worked for me.
We can use LINQ to do this and still use foreach as asked:
As @tvanfosson said, the enumerator returns the file names as strings, not the
HttpPostedFileBase
. This methodHttpPostedFileBase this[string name]
returns the object we want. IfHttpFileCollectionBase
implementedIEnumerable<HttpPostedFileBase>
then we could do the foreach normally. However, it implements a non-genericIEnumerable
.Unfortunately tvanfosson's answer did not work for me. Although the files would upload just fine, and no error would be thrown, a problem would occur where only one of the files would be used, so the same file would be saved twice rather than using them both.
It seemed to be a problem with the foreach statement looping through the names of each file in the Request.Files, for some reason it wasn't working as a key for me, and only the first file would be selected every time.
You might try iterating the strings and casting them to HttpPostedFile instead, like this:
With my tab HTML is:
Request.Files will have duplicate name in array. So you should solve like this: