c# - mvc - propiedades fileupload asp net
foreach en Request.Files (6)
Con mi pestaña HTML es:
<input class="valid" id="file" name="file" multiple="" type="file">
Request.Files tendrá un nombre duplicado en la matriz. Entonces deberías resolverlo así:
for (int i = 0; i < Request.Files.Count; i++ ){
HttpPostedFileBase fileUpload = Request.Files[i];
Estoy intentando subir varios archivos en ASP.NET MVC y tengo este sencillo bucle foreach en mi controlador
foreach (HttpPostedFileBase f in Request.Files)
{
if (f.ContentLength > 0)
FileUpload(f);
}
El código anterior genera este error:
Unable to cast object of type ''System.String'' to type ''System.Web.HttpPostedFile''.
Lo que no entiendo es por qué Request.Files [1] devuelve un HttpPostedFileBase pero cuando se repite, devuelve cadenas (presumiblemente los nombres de los archivos).
Nota: Sé que esto se puede resolver con un bucle for. Además, traté de usar HttpPostedFile, con el mismo error.
El enumerador en HttpFileCollection
devuelve las claves (nombres) de los archivos, no los objetos HttpPostedFileBase
. Una vez que obtenga la clave, use la propiedad Item
( []
) con la clave (nombre de archivo) para obtener el objeto HttpPostedFileBase
.
foreach (string fileName in Request.Files)
{
HttpPostedFileBase file = Request.Files[fileName];
...
}
El siguiente código funcionó para mí.
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;
}
Lamentablemente la respuesta de Tvanfosson no funcionó para mí. Aunque los archivos se cargarían muy bien y no se generaría ningún error, se produciría un problema donde solo se usaría uno de los archivos, por lo que el mismo archivo se guardaría dos veces en lugar de usar ambos.
Parecía ser un problema con la instrucción foreach al recorrer los nombres de cada archivo en Request.Files, por alguna razón no funcionaba como clave para mí, y solo se seleccionaba el primer archivo cada vez.
HttpFileCollectionBase files = Request.Files;
for(var i = 0; i < files.Count; i++)
{
HttpPostedFileBase file = files[i];
...
}
Podemos usar LINQ para hacer esto y seguir usando foreach como se le pidió:
var files = Enumerable.Range(0, Request.Files.Count)
.Select(i => Request.Files[i]);
foreach (var file in files)
{
// file.FileName
}
Como dijo @tvanfosson, el enumerador devuelve los nombres de los archivos como cadenas, no como HttpPostedFileBase
. Este método HttpPostedFileBase this[string name]
devuelve el objeto que queremos. Si HttpFileCollectionBase
implementó IEnumerable<HttpPostedFileBase>
entonces podríamos hacer el foreach normalmente. Sin embargo, implementa un IEnumerable
no genérico.
Puede intentar iterar las cadenas y convertirlas a HttpPostedFile en su lugar, así:
foreach (string file in Request.Files)
{
HttpPostedFile hFile = Request.Files[file] as HttpPostedFile;
if (hFile.ContentLength > 0)
FileUpload(hFile);
}