在request.Files上进行foreach


75

我正在尝试在ASP.NET MVC中上传多个文件,并且我的控制器中有这个简单的foreach循环

foreach (HttpPostedFileBase f in Request.Files)
{
    if (f.ContentLength > 0)
        FileUpload(f);
}

先前的代码会产生此错误:

Unable to cast object of type 'System.String' to type 'System.Web.HttpPostedFile'. 

我不明白的是为什么Request.Files [1]返回HttpPostedFileBase,但是当它进行迭代时,它返回字符串(大概是文件名)。

注意:我知道这可以通过for循环解决。另外,我尝试使用HttpPostedFile,但出现相同的错误。

Answers:


111

HttpFileCollection返回上的枚举数返回文件的键(名称),而不是HttpPostedFileBase对象。获取密钥后,将Item[])属性与密钥(文件名)一起使用以获取HttpPostedFileBase对象。

foreach (string fileName in Request.Files)
{
    HttpPostedFileBase file = Request.Files[fileName];

    ...
}

1
有没有办法让它返回HttpPostedFile呢?
奥马尔

从来没听说过。它从NameObjectCollectionBase派生而来,该类的枚举数遍历键。
tvanfosson,2009年

编译器向我抛出错误,希望我使用HttpPostedFileBase而不是HttpPostedFile
科迪2013年

在我的情况下,@ tvanfosson fileName始终变为“ Image”,但是当我说Request.Files [0] .FileName时,它给出正确的名称了吗?我正在使用MVC5。
Geethanga 2014年

1
@Geethanga-作为关键字的“名称”是HTML文件输入标签上的名称,而不是上载的文件的名称。
tvanfosson

36

在我的标签中,HTML是:

<input class="valid" id="file" name="file" multiple="" type="file">

Request.Files在数组中将具有重复的名称。所以你应该这样解决:

for (int i = 0; i < Request.Files.Count; i++ ){
    HttpPostedFileBase fileUpload = Request.Files[i];

这对我来说比答案更好,因为正如他们的html所指出的,它允许在同一文件输入中包含多个文件。
Caffeinius

4
这是正确的答案,因为您应该可以使用来获取文件名file.FileName。如果您这样做foreach并具有重复的名称,则第一个文件将被保存多次
Arijoon,

13

我们可以使用LINQ来做到这一点,并且仍然按照要求使用foreach:

var files = Enumerable.Range(0, Request.Files.Count)
    .Select(i => Request.Files[i]);

foreach (var file in files)
{
    // file.FileName
}

正如@tvanfosson所说,枚举器将文件名作为字符串而不是HttpPostedFileBase。返回。此方法HttpPostedFileBase this[string name]返回我们想要的对象。如果HttpFileCollectionBase实施的IEnumerable<HttpPostedFileBase>话,我们可以正常进行foreach。但是,它实现了非泛型IEnumerable


6

您可以尝试迭代字符串并将其转换为HttpPostedFile,如下所示:

foreach (string file in Request.Files)
    {
        HttpPostedFile hFile = Request.Files[file] as HttpPostedFile;
        if (hFile.ContentLength > 0)
            FileUpload(hFile);
    }

3
无法将HttpPostedFileBase隐式转换为HttpPostedFile
Ifeanyi Chukwu 2013年

6

不幸的是,tvanfosson的答案对我没有用。尽管这些文件可以正常上传,并且不会引发任何错误,但是会出现一个问题,即仅使用其中一个文件,因此同一文件将被保存两次,而不是同时使用它们。

foreach语句遍历Request.Files中每个文件的名称似乎是一个问题,由于某种原因,它并不是我的关键,每次都只会选择第一个文件。

HttpFileCollectionBase files = Request.Files;

for(var i = 0; i < files.Count; i++)
{
    HttpPostedFileBase file = files[i];

    ...
}

这是我们在iOS上遇到的问题,因为“拍照”功能将每个文件命名为“ image.jpg”,但是此更改解决了它。谢谢。
布莱恩·戴维斯

4

以下代码对我有用。

  HttpResponseMessage result = null;
  var httpRequest = System.Web.HttpContext.Current.Request;
  HttpFileCollection uploadFiles = httpRequest.Files;
  var docfiles = new List<string>();

  if (httpRequest.Files.Count > 0){
      int i;
      for (i = 0; i < uploadFiles.Count; i++) {
          HttpPostedFile postedFile = uploadFiles[i];
          var filePath = @"C:/inetpub/wwwroot/test1/reports/" + postedFile.FileName;
          postedFile.SaveAs(filePath);
          docfiles.Add(filePath);
      }
      result = Request.CreateResponse(HttpStatusCode.Created, docfiles);
  } else {
      result = Request.CreateResponse(HttpStatusCode.BadRequest);
  }

  return result;
}

0

您可以像这样HttpPostedFile摆脱HttpFileCollection使用foreach

foreach (var obj in fileCollection)
{
    HttpPostedFile file = fileCollection.Get(obj.ToString());
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.