Foreach on Request.Files
Я пытаюсь загрузить несколько файлов в 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 с той же ошибкой.
Ответы
Ответ 1
Перечислитель на HttpFileCollection
возвращает ключи (имена) файлов, а не объекты HttpPostedFileBase
. Как только вы получите ключ, используйте свойство Item
([]
) с ключом (имя файла), чтобы получить объект HttpPostedFileBase
.
foreach (string fileName in Request.Files)
{
HttpPostedFileBase file = Request.Files[fileName];
...
}
Ответ 2
С моей вкладкой 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];
Ответ 3
Мы можем использовать 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
.
Ответ 4
Вместо этого вы можете попробовать выполнить итерацию строк и перебросить их в HttpPostedFile следующим образом:
foreach (string file in Request.Files)
{
HttpPostedFile hFile = Request.Files[file] as HttpPostedFile;
if (hFile.ContentLength > 0)
FileUpload(hFile);
}
Ответ 5
К сожалению, ответ tvanfosson не работал у меня. Несмотря на то, что файлы будут загружаться просто отлично, и никакая ошибка не будет выбрана, возникнет проблема, когда будет использоваться только один из файлов, поэтому один и тот же файл будет сохранен дважды, а не использовать их оба.
Казалось, что проблема в том, что оператор foreach зацикливается на имена каждого файла в файле Request.Files, по какой-то причине он не работал как ключ для меня, и только первый файл выбирался каждый раз.
HttpFileCollectionBase files = Request.Files;
for(var i = 0; i < files.Count; i++)
{
HttpPostedFileBase file = files[i];
...
}
Ответ 6
Следующий код работал у меня.
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;
}
Ответ 7
Вы можете получить HttpPostedFile
из HttpFileCollection
используя foreach
например так:
foreach (var obj in fileCollection)
{
HttpPostedFile file = fileCollection.Get(obj.ToString());
}