6

¿Cuál es el mejor método para cargar archivos de tamaño variable (ya sea muy grande o muy pequeño para un sistema de archivos de aplicación ASP.NET MVC 2)?¿Cuál es la mejor manera de cargar archivos con ASP.NET MVC 2?

Esto es lo que entiendo hasta ahora:

Parece que hay dos maneras en que las personas se ocupan de esto. (Vamos a suponer que los archivos pueden ser muy grandes o muy pequeños)

(1) Manejar la carga en una acción de control a través de Request.Files o HttpPostedFileBase, que parece tener una desventaja de tomar mucho tiempo porque ASP.NET carga los archivos en la memoria activa.

o

(2) interceptar la carga de archivos desde el principio con un HttpModule que de alguna manera evita el problema de rendimiento. (Estoy un poco nublado sobre cómo funciona esto, pero he estado usando este post http://darrenjohnstone.net/2008/07/15/aspnet-file-upload-module-version-2-beta-1/ como referencia). La parte de la que estoy confundido es en qué punto ASP.NET carga los archivos enviados a la memoria activa, y cómo la interceptación en un módulo realmente cambia este comportamiento.

Como la segunda opción es más rápida, parece ser la mejor opción. Pero parece que una aplicación que envía un formulario de carga probablemente tenga algunos datos asociados con el archivo que necesita persistir en una base de datos. No quiero hacer llamadas de persistencia en mi HttpHandler o HttpModule, (porque entonces tendré dos funcionalidades muy similares que ocurren en diferentes lugares: el controlador y el controlador http).

Supongo que una solución sería almacenar la ubicación del archivo de destino en HttpContext.Items, pero es la mejor manera?

Una última preocupación sobre esto es que quiero renderizar una HttpResponse antes de que el archivo termine de cargarse. Entonces, si hay un archivo grande, enviaré al usuario una vista con el valor del estado de carga y hago llamadas AJAX para mantener el estado actualizado. ¿Cómo presento un resultado mientras sigo el proceso de carga? ¿Necesito hacer un AsyncHandler o AsyncController? ¿Necesito tomar otro hilo manualmente?

Muchas gracias chicos. Sé que esta es una gran cantidad de preguntas, y probablemente refleja una falta general de comprensión sobre algo. Lo curioso de las carencias generales de comprensión es que las personas que las tienen también tienden a carecer de la comprensión de qué comprensión les falta ... así que, si alguien puede indicarme la dirección correcta en esa nota también, lo agradecería. .

+0

posible duplicación de [File upload MVC] (http://stackoverflow.com/questions/765211/file-upload-mvc) – jgauffin

+0

¿Está bromeando? – smartcaveman

+0

@jguaffin: la pregunta a la que se vincula no está relacionada en absoluto con este problema. – Fenton

Respuesta

2

Si mal no recuerdo de ASP.NET 2.0, los archivos grandes se van a enjuagar en el disco, por lo que incluso utilizando HttpPostedFileBase no debería haber problemas de memoria/rendimiento. No estoy seguro de que asynccontrollers sea una solución aquí, asynccontrollers es para procesos de servidor de larga ejecución.Para ver un ejemplo de AsyncControllers, vea http://www.aaronstannard.com/post/2011/01/06/asynchonrous-controllers-ASPNET-mvc.aspx

+0

¿Quiere decir eso como una regla general con respecto a AsyncController y AJAX? ¿Por qué sería eso? – smartcaveman

+0

cambié mi respuesta la línea sobre ajax y asynccontrollers era falsa – Wim

+0

¿Está usando http://www.uploadify.com/ en el lado del cliente y un simple HttpPostedFileBase en el lado del servidor no es una solución a su problema? – Wim

0

Yo uso este javascript tool

Este es el controlador (I comprobar IE de causa tiene un comportamiento extraño):

<HttpPost()> _ 
Function UploadExcelPriceList(ByVal id As String) As System.String 

    Dim bResult As Boolean = False 
    Dim IsIE As Boolean = False 
    Dim sFileName As String = "" 

    If (Request.Files Is Nothing) OrElse (Request.Files.Count = 0) Then 
     If String.IsNullOrEmpty(Request.Params("qqfile")) Then 
      Return ("{success:false, error:'request file is empty'}") 
     Else 
      sFileName = Request.Params("qqfile").ToString 
     End If 
    Else 
     sFileName = Request.Files(0).FileName 
     IsIE = True 
    End If 

    If String.IsNullOrEmpty(sFileName) Then 
     Return ("{success:false, error:'request file is empty'}") 
    End If 

    Dim DocumentName As String = Id & Path.GetExtension(sFileName) 

    If IsIE Then 
     Try 
      Request.Files(0).SaveAs(Path.Combine(My.Settings.TempFolder, DocumentName)) 
     Catch ex As Exception 
      Return ("{success:false, error:'" & ex.Message & "'}") 
     End Try 
    Else 
     Try 
      If (Request.InputStream IsNot Nothing) AndAlso (Request.InputStream.CanRead) AndAlso (Request.InputStream.Length > 0) Then 
       Using fileStream As FileStream = New FileStream(Path.Combine(My.Settings.TempFolder, DocumentName), FileMode.Create) 
        Dim FileBytes(Core.Convert.ToInt32(Request.InputStream.Length)) As Byte 
        Dim bytesRead As Int32 = 0 
        bytesRead = Request.InputStream.Read(FileBytes, 0, FileBytes.Length) 
        fileStream.Write(FileBytes, 0, bytesRead) 
        fileStream.Flush() 
        fileStream.Close() 
        bytesRead = Nothing 
       End Using 
      End If 
     Catch ex As Exception 
      Return ("{success:false, error:'" & ex.Message & "'}") 
     End Try 
    End If 

    Return ("{success:true, id: '" & Id & "'}") 

End Function 

Puedo poner este código HTML en mi opinión:

<div id="PopupExcelUploader" title="Carica Listino Excel"> 
    <div id="uploaderFile"></div> 
</div> 

y este es el javascript:

function CreateFileUploader() { 
    var uploader = new qq.FileUploader({ 
     element: $('#uploaderFile')[0], 
     template: '<div class="qq-uploader">' + 
           '<div class="qq-upload-drop-area"><span>Drop files here to upload</span></div>' + 
           '<div class="qq-upload-button ui-button ui-widget ui-corner-all ui-button-text-only ui-state-default">Seleziona il Listino Excel</div>' + 
           '<ul class="qq-upload-list"></ul>' + 
           '</div>', 
     hoverClass: 'ui-state-hover', 
     focusClass: 'ui-state-focus', 
     action: UploaderAction, 
     allowedExtensions: ['xls', 'xlsx'], 
     params: { id: ModelId }, 
     onSubmit: function(file, ext) { 
     }, 
     onComplete: function(id, fileName, responseJSON) { 
      if ((responseJSON.success == null) || (responseJSON.success == 'false')) { 
       $.jGrowl("Error!", { theme: 'MessageError', life: 3000 }); 
      } 
      else { 
       documentUploaded = true; 
       $.jGrowl("Document uploaded successfully!", { theme: 'MessageOk', life: 1800 }); 
       window.setTimeout(function() { 
        $("#PopupExcelUploader").dialog('close'); 
        $("#PriceListDynamicGrid").trigger("reloadGrid"); 
       }, 3000); 
      } 
     } 
    }); 
} 
+0

Gracias por el ejemplo de código, pero esto no aborda la pregunta. – smartcaveman

Cuestiones relacionadas