2011-03-03 19 views
16

Estoy tratando de implementar la carga del archivo arrastrar y soltar del estilo de Gmail en ASP.NET MVC.File API File Upload - Leer XMLHttpRequest en ASP.NET MVC

He estado siguiendo este artículo: http://robertnyman.com/html5/fileapi-upload/fileapi-upload.html y quiero publicar archivos cargados en una acción del controlador MVC.

Para ello, he modificado la muestra JavaScript script en el enlace para que apunte a mi acción del controlador:

xhr.open("post", "/home/UploadFiles", true); 

Aquí es mi acción del controlador:

[HttpPost] 
public virtual string UploadFiles(object obj) 
{ 
    var length = Request.ContentLength; 
    var bytes = new byte[length]; 
    Request.InputStream.Read(bytes, 0, length); 
    // var bytes has byte content here. what do do next? 

    return "Files uploaded!"; 
} 

puse un punto de interrupción, y cuando cargo un archivo, se llega al punto de interrupción, lo cual es bueno. Pero, ¿cómo puedo extraer los datos del objeto XMLHttpRequest cargado (javascript)? No creo que esté en HttpRequest, ¿es el parámetro? Si es así, ¿de qué tipo debo esperar & cómo extraigo la matriz de bytes y extraigo la información del archivo cargado desde ella?

(estoy usando Chrome - Yo sé que no funciona en IE)

Cualquier sugerencia sería muy apreciada!

Respuesta

38

Lo descubrí. Aquí está el código C#:

[HttpPost] 
    public virtual string UploadFiles(object obj) 
    { 
     var length = Request.ContentLength; 
     var bytes = new byte[length]; 
     Request.InputStream.Read(bytes, 0, length); 
     // bytes has byte content here. what do do next? 

     var fileName = Request.Headers["X-File-Name"]; 
     var fileSize = Request.Headers["X-File-Size"]; 
     var fileType = Request.Headers["X-File-Type"]; 

     var saveToFileLoc = string.Format("{0}\\{1}", 
             Server.MapPath("/Files"), 
             fileName); 

     // save the file. 
     var fileStream = new FileStream(saveToFileLoc, FileMode.Create, FileAccess.ReadWrite); 
     fileStream.Write(bytes, 0, length); 
     fileStream.Close(); 

     return string.Format("{0} bytes uploaded", bytes.Length); 
    } 

Y aquí está el código Javascript:

<script type="text/javascript"> 
(function() 
{ 
    var filesUpload = document.getElementById("files-upload"); 
    var dropArea = document.getElementById("drop-area"); 
    var fileList = document.getElementById("file-list"); 

    function uploadFile(file) 
    { 
     var li = document.createElement("li"); 
     var progressBarContainer = document.createElement("div"); 
     var progressBar = document.createElement("div"); 

     progressBarContainer.className = "progress-bar-container"; 
     progressBar.className = "progress-bar"; 
     progressBarContainer.appendChild(progressBar); 
     li.appendChild(progressBarContainer); 

     // Uploading - for Firefox, Google Chrome and Safari 
     var xhr = new XMLHttpRequest(); 

     // Update progress bar 
     xhr.upload.addEventListener("progress", function (evt) 
     { 
      if (evt.lengthComputable) 
      { 
       progressBar.style.width = (evt.loaded/evt.total) * 100 + "%"; 
      } 
     }, false); 

     // File uploaded 
     xhr.addEventListener("load", function() 
     { 
      progressBarContainer.className += " uploaded"; 
      progressBar.innerHTML = "Uploaded!"; 
     }, false); 

     xhr.open("post", "/home/UploadFile", true); 

     // Set appropriate headers 
     xhr.setRequestHeader("Content-Type", "multipart/form-data"); 
     xhr.setRequestHeader("X-File-Name", file.fileName); 
     xhr.setRequestHeader("X-File-Size", file.fileSize); 
     xhr.setRequestHeader("X-File-Type", file.type); 

     // Send the file 
     xhr.send(file); 

     // Present file info and append it to the list of files 
     var div = document.createElement("div"); 
     li.appendChild(div); 
     var fileInfo = "<div><strong>Name:</strong> " + file.name + "</div>"; 
     fileInfo += "<div><strong>Size:</strong> " + parseInt(file.size/1024, 10) + " kb</div>"; 
     fileInfo += "<div><strong>Type:</strong> " + file.type + "</div>"; 
     div.innerHTML = fileInfo; 

     // insert at beginning of list. 
     fileList.insertBefore(li, fileList.firstChild); 

     // or insert at end of list. 
     //fileList.appendChild(li); 
    } 

    function traverseFiles(files) 
    { 
     if (typeof files !== "undefined") 
     { 
      for (var i = 0, l = files.length; i < l; i++) 
      { 
       uploadFile(files[i]); 
      } 
     } 
     else 
     { 
      fileList.innerHTML = "No support for the File API in this web browser"; 
     } 
    } 

    filesUpload.addEventListener("change", function() 
    { 
     traverseFiles(this.files); 
    }, false); 

    dropArea.addEventListener("dragleave", function (evt) 
    { 
     var target = evt.target; 

     if (target && target === dropArea) 
     { 
      this.className = ""; 
     } 
     evt.preventDefault(); 
     evt.stopPropagation(); 
    }, false); 

    dropArea.addEventListener("dragenter", function (evt) 
    { 
     this.className = "over"; 
     evt.preventDefault(); 
     evt.stopPropagation(); 
    }, false); 

    dropArea.addEventListener("dragover", function (evt) 
    { 
     evt.preventDefault(); 
     evt.stopPropagation(); 
    }, false); 

    dropArea.addEventListener("drop", function (evt) 
    { 
     //document.getElementById("file-list").innerHTML = ""; 

     traverseFiles(evt.dataTransfer.files); 
     this.className = ""; 
     evt.preventDefault(); 
     evt.stopPropagation(); 
    }, false); 
})(); 
+0

Supuse que guardar el byte de solicitud [] sería un documento XML, no el contenido del archivo en sí. Terminó siendo mucho más simple de lo que esperaba. –

+2

+1 para guardar mi tarde – Valentin

+0

Buen código. Está funcionando, WooHoo ~~~ – HorseKing

0

Esto es grande. Mejorado ligeramente:

xhr.setRequestHeader("X-File-Name", file.name); 
xhr.setRequestHeader("X-File-Size", file.size); 
Cuestiones relacionadas