subir net mvc multiples imagenes guardar descargar con como asp archivos archivo c# jquery asp.net-mvc file-upload plupload

net - subir imagenes c# mvc



¿Cómo subir archivos grandes usando MVC 4? (3)

Lo tenía funcionando ... pero noté que una vez que los archivos que estaba cargando se hacen más grandes (alrededor de 4000k) el controlador no se llamaría ...

Así que agregué en fragmentación lo que solucionó ese problema ... pero ahora cuando abro el archivo está lleno de caracteres basura ...

Entonces, ¿cuál es la forma correcta de cargar archivos de gran tamaño con plupload / MVC 4?

Aquí está mi código actual

$(document).ready(function () { var uploader = new plupload.Uploader({ runtimes: ''html5'', browse_button: ''pickfiles'', container: ''container'', // max_file_size: ''20000mb'', url: ''@Url.Action("Upload", "Home")'', chunk_size: ''4mb'', //filters: [ // { title: "Excel files", extensions: "xls,xlsx" }, // { title: "Text files", extensions: "txt" } //], multiple_queues: true, multipart: true, multipart_params: { taskId: '''' } });

y el controlador

[HttpPost] public ActionResult Upload(int? chunk, string name, string taskId) { string filePath = ""; var fileUpload = Request.Files[0]; var uploadPath = Server.MapPath("~/App_Data/Uploads"); chunk = chunk ?? 0; string uploadedFilePath = Path.Combine(uploadPath, name); var fileName = Path.GetFileName(uploadedFilePath); try { using (var fs = new FileStream(filePath, chunk == 0 ? FileMode.Create : FileMode.Append)) { var buffer = new byte[fileUpload.InputStream.Length]; fileUpload.InputStream.Read(buffer, 0, buffer.Length); fs.Write(buffer, 0, buffer.Length); } //Log to DB for future processing InstanceExpert.AddProcessStart(filePath, Int32.Parse(taskId)); }


En web.config necesita estos (2GB en todo):

<system.web> <compilation debug="true" targetFramework="4.5" /> <httpRuntime targetFramework="4.5" maxRequestLength="2147483647" executionTimeout="1600" requestLengthDiskThreshold="2147483647" /> <security> <requestFiltering> <requestLimits maxAllowedContentLength="2147483647" /> </requestFiltering> </security> ... </system.web>


Tuve este problema y encontré la solución basada en el código de Jonathan aquí . Hay algún problema con su código, pero esta es mi solución. Si desea cargar un archivo grande, algo así como un archivo de video de 1Gb, debe tirar el archivo y enviarlo a través de varias solicitudes (una solicitud da tiempo de espera). primero establece el límite máximo para el lado del cliente y del servidor en Web.config como se explica en otras respuestas.

<system.webServer> <security> <requestFiltering> <requestLimits maxAllowedContentLength="2147483647" /> </requestFiltering> </security> <system.webServer>

y

<system.web> <httpRuntime targetFramework="4.5" maxRequestLength="2147483647" /> </system.web>

luego, corta el archivo y envía cada tirada, espera la respuesta y envía el siguiente trozo. aquí está el html ( VideoDiv funciona como panel de carga), javascript (jQuery) y el código del controlador.

<div id="VideoDiv"> <label>Filename:</label> <input type="file" id="fileInput" /><br/><br/> <input type="button" id="btnUpload" value="Upload a presentation"/><br/><br/> <div id="progressbar_container" style="width: 100%; height: 30px; position: relative; background-color: grey; display: none"> <div id="progressbar" style="width: 0%; height: 100%; position: absolute; background-color: green"></div> <span id="progressbar_label" style="position: absolute; left: 35%; top: 20%">Uploading...</span> </div> </div>

Código de Javascript para lanzar, control de llamadas y barra de progreso de actualización:

var progressBarStart = function() { $("#progressbar_container").show(); } var progressBarUpdate = function (percentage) { $(''#progressbar_label'').html(percentage + "%"); $("#progressbar").width(percentage + "%"); } var progressBarComplete = function() { $("#progressbar_container").fadeOut(500); } var file; $(''#fileInput'').change(function(e) { file = e.target.files[0]; }); var uploadCompleted = function() { var formData = new FormData(); formData.append(''fileName'', file.name); formData.append(''completed'', true); var xhr2 = new XMLHttpRequest(); xhr2.onload = function() { progressBarUpdate(100); progressBarComplete(); } xhr2.open("POST", "/Upload/UploadComplete?fileName=" + file.name + "&complete=" + 1, true); xhr2.send(formData); } var multiUpload = function(count, counter, blob, completed, start, end, bytesPerChunk) { counter = counter + 1; if (counter <= count) { var chunk = blob.slice(start, end); var xhr = new XMLHttpRequest(); xhr.onload = function() { start = end; end = start + bytesPerChunk; if (count == counter) { uploadCompleted(); } else { var percentage = (counter / count) * 100; progressBarUpdate(percentage); multiUpload(count, counter, blob, completed, start, end, bytesPerChunk); } } xhr.open("POST", "/Upload/MultiUpload?id=" + counter.toString() + "&fileName=" + file.name, true); xhr.send(chunk); } } $("#VideoDiv").on("click", "#btnUpload", function() { var blob = file; var bytesPerChunk = 3757000; var size = blob.size; var start = 0; var end = bytesPerChunk; var completed = 0; var count = size % bytesPerChunk == 0 ? size / bytesPerChunk : Math.floor(size / bytesPerChunk) + 1; var counter = 0; progressBarStart(); multiUpload(count, counter, blob, completed, start, end, bytesPerChunk); });

y aquí está el controlador de carga para almacenar el chucnk ("App_Data / Videos / Temp") y luego fusionarlos y almacenarlos ("App_Data / Videos"):

public class UploadController : Controller { private string videoAddress = "~/App_Data/Videos"; [HttpPost] public string MultiUpload(string id, string fileName) { var chunkNumber = id; var chunks = Request.InputStream; string path = Server.MapPath(videoAddress+"/Temp"); string newpath = Path.Combine(path, fileName+chunkNumber); using (FileStream fs = System.IO.File.Create(newpath)) { byte[] bytes = new byte[3757000]; int bytesRead; while ((bytesRead=Request.InputStream.Read(bytes,0,bytes.Length))>0) { fs.Write(bytes,0,bytesRead); } } return "done"; } [HttpPost] public string UploadComplete(string fileName, string complete) { string tempPath = Server.MapPath(videoAddress + "/Temp"); string videoPath = Server.MapPath(videoAddress); string newPath = Path.Combine(tempPath, fileName); if (complete=="1") { string[] filePaths = Directory.GetFiles(tempPath).Where(p=>p.Contains(fileName)).OrderBy(p => Int32.Parse(p.Replace(fileName, "$").Split(''$'')[1])).ToArray(); foreach (string filePath in filePaths) { MergeFiles(newPath, filePath); } } System.IO.File.Move(Path.Combine(tempPath, fileName),Path.Combine(videoPath,fileName)); return "success"; } private static void MergeFiles(string file1, string file2) { FileStream fs1 = null; FileStream fs2 = null; try { fs1 = System.IO.File.Open(file1, FileMode.Append); fs2 = System.IO.File.Open(file2, FileMode.Open); byte[] fs2Content = new byte[fs2.Length]; fs2.Read(fs2Content, 0, (int) fs2.Length); fs1.Write(fs2Content, 0, (int) fs2.Length); } catch (Exception ex) { Console.WriteLine(ex.Message + " : " + ex.StackTrace); } finally { if (fs1 != null) fs1.Close(); if (fs2 != null) fs2.Close(); System.IO.File.Delete(file2); } } }

Sin embargo, si dos usuarios al mismo tiempo cargan archivos con el mismo nombre, habrá algún problema y deberá manejar este problema. Al leer responseText, puede detectar algunos errores y excepciones y recortarlo.


Versión actual

Según la descripción detallada del error de IIS 8.0, que es la versión que utilicé en el momento en que escribí esta respuesta, debe verificar la configuration/system.webServer/security/requestFiltering/requestLimits @maxAllowedContentLength configurada en ApplicationHost.config o Web.config archivo Web.config Eso significa que debes incluir:

<requestLimits maxAllowedContentLength="20971520000"></requestLimits>

dentro de la configuración / system.webServer / security / request Filtrado del árbol de etiquetas. En caso de que carezca de la imaginación para visualizar a dónde va, el bloque de código completo es como el siguiente:

<configuration> <system.webServer> <security> <requestFiltering> <requestLimits maxAllowedContentLength="20971520000"></requestLimits> </requestFiltering> </security> </system.webServer> </configuration>

Visual Studio 2010 / .Net Framework 4 y anteriores

También es posible que las aplicaciones web heredadas creadas con VS2008 / 10 y / o .Net Framework 3.5 / 4 aún puedan estar buscando esta configuración a través de configuration/system.web/httpRuntime @maxRequestLength, pero como lo demuestra la página enlazada, es ya no está disponible, aunque HttpRuntime Class , que no se aplica a este escenario, todavía existe desde .Net Framework 1.1. Si este es el caso, debe incluir:

<httpRuntime maxRequestLength="20971520000" />

inside configuration / system.web / httpRuntime árbol de etiquetas. Una vez más, en caso de que carezca de la comprensión para averiguar dónde se inserta, el bloque de código completo se ve más o menos así:

<configuration> <system.web> <httpRuntime maxRequestLength="20971520000" /> </system.web> </configuration>

El número de tamaño de archivo es simplemente un número arbitrario (20,000 MB, no 20 GB, que sería más bien 21,474,836,480) para mostrar como una demostración. A menos que esté codificando el sitio web para un grupo de seguridad estricto que tiene la necesidad de cargar archivos grandes, no debe permitir que este gran tamaño de archivo se cargue en su servidor web.