foreach по запросу. Файлы - PullRequest
       46

foreach по запросу. Файлы

64 голосов
/ 19 ноября 2009

Я пытаюсь загрузить несколько файлов в 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 с той же ошибкой.

Ответы [ 7 ]

100 голосов
/ 19 ноября 2009

Перечислитель в HttpFileCollection возвращает ключи (имена) файлов, а не объекты HttpPostedFileBase. Получив ключ, используйте свойство Item ([]) с ключом (имя файла), чтобы получить объект HttpPostedFileBase.

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

    ...
}
28 голосов
/ 08 декабря 2014

С моей вкладкой 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];
10 голосов
/ 01 октября 2015

Мы можем использовать 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 голосов
/ 19 ноября 2009

Вместо этого вы можете попробовать перебрать строки и привести их к HttpPostedFile, например:

foreach (string file in Request.Files)
    {
        HttpPostedFile hFile = Request.Files[file] as HttpPostedFile;
        if (hFile.ContentLength > 0)
            FileUpload(hFile);
    }
4 голосов
/ 05 июня 2015

У меня работал следующий код.

  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;
}
4 голосов
/ 09 октября 2014

К сожалению, ответ tvanfosson не сработал для меня. Хотя файлы будут загружаться очень хорошо, и не будет возникать никаких ошибок, возникнет проблема, когда будет использоваться только один из файлов, поэтому один и тот же файл будет сохранен дважды вместо использования обоих.

Казалось, что проблема в том, что оператор foreach просматривал имена каждого файла в Request.Files, по какой-то причине он не работал для меня как ключ, и каждый раз выбирался только первый файл. .

HttpFileCollectionBase files = Request.Files;

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

    ...
}
0 голосов
/ 24 января 2019

Вы можете получить HttpPostedFile из HttpFileCollection, используя foreach, например:

foreach (var obj in fileCollection)
{
    HttpPostedFile file = fileCollection.Get(obj.ToString());
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...