6

Qual è il metodo migliore per caricare file di dimensioni variabili (molto grandi o molto piccoli in un file system dell'applicazione ASP.NET MVC 2)?Qual è il modo migliore per caricare file con ASP.NET MVC 2?

Questo è quello che ho capito finora:

Sembra che ci sono due modi in cui le persone gestiscono questo. (Supponiamo che i file possano essere molto grandi o molto piccoli)

(1) Gestire il caricamento in un'azione controller tramite Request.Files o HttpPostedFileBase, che sembra avere uno svantaggio di richiedere molto tempo perché ASP.NET carica i file nella memoria attiva.

o

(2) intercetta il caricamento di file nella fase iniziale di un modulo Http, che in qualche modo aggira il problema di prestazioni. (Sono un po 'nuvoloso su come funziona, ma sto usando questo post http://darrenjohnstone.net/2008/07/15/aspnet-file-upload-module-version-2-beta-1/ come riferimento). La parte in cui sono confuso riguarda il punto in cui ASP.NET carica i file inviati nella memoria attiva e in che modo l'intercettazione di questo in un modulo modifica effettivamente questo comportamento.

Poiché la seconda opzione è più veloce, sembra l'opzione migliore. Ma sembra che un'applicazione che invia un modulo di caricamento probabilmente avrà alcuni dati associati al file che deve essere conservato in un database. Non voglio effettuare chiamate di persistenza nel mio HttpHandler o HttpModule (perché allora avrò due funzionalità molto simili che si verificano in posti diversi: il controller e il gestore HTTP).

Immagino che una soluzione sarebbe quella di memorizzare la posizione del file di destinazione in HttpContext.Items, ma è questo il modo migliore?

Un ultimo problema è che voglio eseguire il rendering di HttpResponse prima del caricamento del file. Pertanto, se è presente un file di grandi dimensioni, invierò all'utente una vista con il valore dello stato di caricamento e effettuerà chiamate AJAX per mantenere aggiornato lo stato. Come si esegue il rendering di un risultato mentre si continua il processo di caricamento? Devo fare un AsyncHandler o AsyncController? Devo prendere manualmente un altro thread?

Grazie mille ragazzi. So che questo è un sacco di domande e probabilmente riflette una generale mancanza di comprensione di qualcosa. La cosa buffa della mancanza di comprensione generale è che le persone che li hanno tendono anche a non comprendere la comprensione di ciò che manca loro ... quindi, se qualcuno può indicarmi la giusta direzione anche su quella nota, lo apprezzerei .

+0

possibile duplicato di [MVC caricamento file] (http://stackoverflow.com/questions/765211/file-upload-mvc) – jgauffin

+0

Stai scherzando? – smartcaveman

+0

@jguaffin: la domanda a cui ci si collega non è affatto correlata a questo problema. – Fenton

risposta

2

Se ricordo correttamente da ASP.NET 2.0 file di grandi dimensioni vengono scaricati su disco, quindi anche utilizzando HttpPostedFileBase non ci dovrebbero essere problemi di memoria/prestazioni. Non sono sicuro che asyncontrollers sia una soluzione qui, asynccontrollers è per processi server a lunga esecuzione.Per un esempio di AsyncControllers vedi http://www.aaronstannard.com/post/2011/01/06/asynchonrous-controllers-ASPNET-mvc.aspx

+0

Vuoi dire che come regola generale per AsyncController e AJAX? Perché dovrebbe essere? – smartcaveman

+0

cambiato la mia risposta la linea su ajax e asynccontrollers era falsa – Wim

+0

Sta usando http://www.uploadify.com/ sul lato client e un semplice HttpPostedFileBase sul lato server non è una soluzione al tuo problema? – Wim

0

Io uso questo javascript tool

Questo è il controller (I raddoppiare controllo causa IE ha un comportamento strano):

<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 

Ho messo questo codice HTML nel mio Vista:

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

e questo è il 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

Grazie per l'esempio del codice, ma questo non risolve la domanda. – smartcaveman

Problemi correlati