6

Каков наилучший способ для загрузки файлов с переменным размером (очень большой или очень маленький в файловую систему ASP.NET MVC 2)?Каков наилучший способ загрузки файлов с помощью ASP.NET MVC 2?

Это то, что я понимаю, до сих пор:

Похоже, есть два способа, которыми люди справиться с этим. (Предположим, что файлы могут быть очень большими или очень маленькими)

(1) Управлять загрузкой в ​​действии контроллера через Request.Files или HttpPostedFileBase, что, как представляется, имеет недостаток в длительном времени, поскольку ASP.NET загружает файлы в активную память.

или

(2) перехватывают файл загрузки на ранней стадии с HttpModule, который как-то обходит проблему производительности. (Я немного облачно, как это работает, но я использовал этот пост http://darrenjohnstone.net/2008/07/15/aspnet-file-upload-module-version-2-beta-1/ в качестве справки). Часть, с которой я не понятна, в какой момент ASP.NET загружает представленные файлы в активную память, и как перехват этого в модуле действительно изменяет это поведение.

Поскольку второй вариант работает быстрее, он кажется лучшим вариантом. Но похоже, что приложение, отправляющее форму загрузки, вероятно, будет иметь некоторые данные, связанные с файлом, который должен сохраняться в базе данных. Я не хочу делать вызовы с постоянством в HttpHandler или HttpModule (потому что тогда у меня будут две очень похожие функции, встречающиеся в разных местах: контроллер и обработчик http).

Я думаю, что одна работа вокруг будет хранить местоположение целевого файла в HttpContext.Items, но это лучший способ?

Последнее беспокойство в том, что я хочу отобразить HttpResponse до того, как файл завершит загрузку. Итак, если есть большой файл, я отправлю пользователю представление со значением состояния загрузки и сделаю вызовы AJAX, чтобы сохранить статус обновленным. Как сделать результат, сохраняя процесс загрузки? Мне нужно сделать AsyncHandler или AsyncController? Нужно ли вручную захватывать другой поток?

Большое спасибо, ребята. Я знаю, что это много вопросов и, вероятно, отражает общее отсутствие понимания чего-то. Самое смешное в общем недостатке понимания состоит в том, что у людей, у которых есть их, также не хватает понимания того, что им не хватает ... поэтому, если кто-то может указать мне в правильном направлении и на эту заметку, я был бы признателен ,

+0

Возможный дубликат [Загрузка файла MVC] (http://stackoverflow.com/questions/765211/file-upload-mvc) – jgauffin

+0

Вы шутите? – smartcaveman

+0

@jguaffin - вопрос, на который вы ссылаетесь, вообще не связан с этой проблемой. – Fenton

ответ

2

Если я правильно помню из ASP.NET 2.0, большие файлы сбрасываются на диск, поэтому даже с использованием HttpPostedFileBase не должно быть проблем с памятью/производительностью. Я не уверен, что asynccontrollers - это решение здесь, asynccontrollers для длительных серверных процессов.Пример для AsyncControllers см. http://www.aaronstannard.com/post/2011/01/06/asynchonrous-controllers-ASPNET-mvc.aspx

+0

Вы имеете в виду это как правило относительно AsyncController и AJAX? Почему это так? – smartcaveman

+0

изменил мой ответ, строка о ajax и asynccontrollers была ложной – Wim

+0

Использует ли http://www.uploadify.com/ на стороне клиента и простой HttpPostedFileBase на стороне сервера не решение вашей проблемы? – Wim

0

Я использую этот JavaScript tool

Это контроллер (я дважды проверить причину IE имеет странное поведение):

<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 

Я положил этот HTML на мой взгляд:

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

и это 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

Благодарим вас за образец кода, но это не касается вопроса. – smartcaveman