Каков наилучший способ загрузки файлов с помощью 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.Предметы, но это лучший способ?
последняя проблема заключается в том, что я хочу отобразить HttpResponse до завершения загрузки файла. Итак, если есть большой файл, я отправлю пользователю представление со значением статуса загрузки и сделаю AJAX-вызовы для обновления статуса. как мне визуализировать результат, сохраняя при этом процесс загрузки? Делать Мне нужно сделать AsyncHandler или AsyncController? Мне нужно вручную захватить другую нить?
большое спасибо, ребята. Я знаю, что это много вопросов и, вероятно, отражает общее непонимание чего-то. Забавная вещь об общих недостатках понимания заключается в том, что люди, у которых они есть, также, как правило, не понимают, какого понимания им не хватает...поэтому, если кто-то может указать мне в правильном направлении на этой ноте, я был бы признателен он.
2 ответов
Если я правильно помню из ASP.NET 2.0 большие файлы сбрасываются на диск, поэтому даже с помощью HttpPostedFileBase не должно быть никаких проблем с памятью/производительностью. Я не уверен, что asynccontrollers-это решения здесь, asynccontrollers для длительных серверных процессов. Пример off AsyncControllers см. В разделе http://www.aaronstannard.com/post/2011/01/06/asynchonrous-controllers-ASPNET-mvc.aspx
Я использую этот javascript инструмент
это контроллер (я дважды проверяю причину 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);
}
}
});
}