2009-11-19 26 views
53

Estoy intentando cargar varios archivos en ASP.NET MVC y yo tenemos este sencillo bucle foreach en mi controlador deforeach en Request.Files

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.

Respuesta

85

El empadronador en los HttpFileCollection devuelve las claves (nombres) de los archivos, no los HttpPostedFileBase objetos. 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]; 

    ... 
} 
+1

¿Hay alguna manera de que devuelva un HttpPostedFile en su lugar? – Omar

+0

No que yo sepa. Se deriva de NameObjectCollectionBase y el enumerador de esa clase itera sobre las claves. – tvanfosson

+0

El compilador arroja un error para mí y quiere que use 'HttpPostedFileBase' en lugar de' HttpPostedFile'. – Cody

5

Usted puede tratar de la iteración de las cuerdas y la fundición a HttpPostedFile lugar, como este:

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

no se puede convertir HttpPostedFileBase implícitamente a HttpPostedFile –

3

Desafortunadamente 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 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 hora.

HttpFileCollectionBase files = Request.Files; 

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

    ... 
} 
21

Con mi ficha HTML es:

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

Request.Files tendrán nombre duplicado en la matriz. Así que debe resolver de esta manera:

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

Esta funcionó mejor que la respuesta porque, como señala su html, permite varios archivos en la misma entrada de archivo. – Caffeinius

+2

Esta es la respuesta correcta, ya que debería poder obtener el nombre del archivo con 'file.FileName'. Si lo haces con 'foreach' y tienes nombres duplicados, el primer archivo se guardará varias veces – Arijoon

4

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; 
} 
10

Podemos utilizar LINQ para hacer esto y seguir utilizando foreach, tal como solicitó:

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

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

Como @tvanfosson Dicho esto, el empadronador devuelve los nombres de archivo como cadenas, no la 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.