使用Asp.Net MVC中的blueimp以块的形式上传文件(Uploading files in chunks with blueimp in Asp.Net MVC)

编程入门 行业动态 更新时间:2024-10-27 02:24:15
使用Asp.Net MVC中的blueimp以块的形式上传文件(Uploading files in chunks with blueimp in Asp.Net MVC)

我尝试将插件blueimp放到我的Asp.Net MVC应用程序中。 我的上传目标大约是1GB。 如何处理服务器端的块文件上传文件?

I try to put the plugin blueimp to my Asp.Net MVC application. My upload target is about 1GB. How to handle chunk file upload fle in server side?

最满意答案

我想你的意思是来自blueimp的FileUpload jquery模块。 这就是我在项目中处理它的方式。 我上传的图片不超过30MB。 所以这个例子只是关于代码,而不是你需要处理1GB文件的事实。

这是javascript代码的一部分。 没什么特别的。 我只关注FileUpload文档和示例。 我只发送了几个属性(包括AntiforgeryToken) - 这些都不是正确行为所必需的。

$("#file-upload").fileupload({ url: 'upload-file', dataType: 'json', autoUpload: false, maxChunkSize: 5000000, progressInterval: 1000, bitrateInterval: 1000 }).on('fileuploadadd', function (e, data) { fileData = data; // save data to be able to submit them later if (window.File && window.Blob) { // update form data data.formData = { uploadFolder: '/upload-folder/some-guid', __RequestVerificationToken: $("#upload-form").find('input[name=__RequestVerificationToken]').val() }; } else { // chunk upload not supported } }); $("#file-submit").on('click', function (e) { e.preventDefault(); fileData.submit(); });

在服务器端,我有一个模型类:

public class UploadViewRequest { public Guid UploadFolder { get; set; } public bool IsChunk { get; set; } public int ChunkNumber { get; set; } public bool IsFirst { get; set; } public bool IsLast { get; set; } public HttpPostedFileBase OriginalFile { get; set; } public bool JsonAccepted { get; set; } }

我为这个类编写了一个自定义模型绑定器,这样我就可以看到它是整个文件还是只是一个块,如果是,那么我将要处理的文件的哪一部分:

public class UploadViewRequestBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { UploadViewRequest model = base.BindModel(controllerContext, bindingContext) as UploadViewRequest; string rangeHeader = controllerContext.HttpContext.Request.Headers["Content-Range"]; if (string.IsNullOrEmpty(rangeHeader)) model.IsChunk = false; else { model.IsChunk = true; Match match = Regex.Match(rangeHeader, "^bytes ([\\d]+)-([\\d]+)\\/([\\d]+)$", RegexOptions.IgnoreCase); int bytesFrom = int.Parse(match.Groups[1].Value); int bytesTo = int.Parse(match.Groups[2].Value); int bytesFull = int.Parse(match.Groups[3].Value); if (bytesTo == bytesFull) model.IsLast = true; else model.IsLast = false; if (bytesFrom == 0) { model.ChunkNumber = 1; model.IsFirst = true; } else { int bytesSize = bytesTo - bytesFrom + 1; model.ChunkNumber = (bytesFrom / bytesSize) + 1; model.IsFirst = false; } } if (controllerContext.HttpContext.Request["HTTP_ACCEPT"] != null && controllerContext.HttpContext.Request["HTTP_ACCEPT"].Contains("application/json")) model.JsonAccepted = true; else model.JsonAccepted = false; return model; } }

这是控制器动作方法:

public ActionResult Upload(UploadViewRequest request) { var path = ''; // create path FileStatus status = null; try { if (request.IsChunk) { if (request.IsFirst ) { // do some stuff that has to be done before the file starts uploading } var inputStream = request.OriginalFile.InputStream; using (var fs = new FileStream(path, FileMode.Append, FileAccess.Write)) { var buffer = new byte[1024]; var l = inputStream.Read(buffer, 0, 1024); while (l > 0) { fs.Write(buffer, 0, l); l = inputStream.Read(buffer, 0, 1024); } fs.Flush(); fs.Close(); } status = new FileStatus(new FileInfo(path)); if (request.IsLast) { // do some stuff that has to be done after the file is uploaded } } else { file.SaveAs(path); status = new FileStatus(new FileInfo(path)); } } catch { status = new FileStatus { error = "Something went wrong" }; } // this is just a browser json support/compatibility workaround if (request.JsonAccepted) return Json(status); else return Json(status, "text/plain"); }

FileStatus类我用作返回值并将其转换为json(对于UploadFile jquery模块):

public class FileStatus { public const string HandlerPath = "/"; public string group { get; set; } public string name { get; set; } public string type { get; set; } public int size { get; set; } public string progress { get; set; } public string url { get; set; } public string thumbnail_url { get; set; } public string delete_url { get; set; } public string delete_type { get; set; } public string error { get; set; } public FileStatus() { } public FileStatus(FileInfo fileInfo) { SetValues(fileInfo.Name, (int)fileInfo.Length, fileInfo.FullName); } public FileStatus(string fileName, int fileLength, string fullPath) { SetValues(fileName, fileLength, fullPath); } private void SetValues(string fileName, int fileLength, string fullPath) { name = fileName; type = "image/png"; size = fileLength; progress = "1.0"; url = HandlerPath + "/file/upload?f=" + fileName; delete_url = HandlerPath + "/file/delete?f=" + fileName; delete_type = "DELETE"; thumbnail_url = "/Content/img/generalFile.png"; } }

I suppose you mean FileUpload jquery module from blueimp. This is how I handle it in my project. I upload large images that don't go over 30MB. So this example is merely about the code, not the fact that you need to handle 1GB files.

This is part of the javascript code. There's nothing special. I just follow the FileUpload documentation and example. I just send couple more properties (inlcuding AntiforgeryToken) - that are not required for the correct behavior.

$("#file-upload").fileupload({ url: 'upload-file', dataType: 'json', autoUpload: false, maxChunkSize: 5000000, progressInterval: 1000, bitrateInterval: 1000 }).on('fileuploadadd', function (e, data) { fileData = data; // save data to be able to submit them later if (window.File && window.Blob) { // update form data data.formData = { uploadFolder: '/upload-folder/some-guid', __RequestVerificationToken: $("#upload-form").find('input[name=__RequestVerificationToken]').val() }; } else { // chunk upload not supported } }); $("#file-submit").on('click', function (e) { e.preventDefault(); fileData.submit(); });

On the server side I have a model class:

public class UploadViewRequest { public Guid UploadFolder { get; set; } public bool IsChunk { get; set; } public int ChunkNumber { get; set; } public bool IsFirst { get; set; } public bool IsLast { get; set; } public HttpPostedFileBase OriginalFile { get; set; } public bool JsonAccepted { get; set; } }

And I wrote a custom model binder for this class, so that I can see if it's whole file or just a chunk and if yes, that what part of the file I'm going to process:

public class UploadViewRequestBinder : DefaultModelBinder { public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { UploadViewRequest model = base.BindModel(controllerContext, bindingContext) as UploadViewRequest; string rangeHeader = controllerContext.HttpContext.Request.Headers["Content-Range"]; if (string.IsNullOrEmpty(rangeHeader)) model.IsChunk = false; else { model.IsChunk = true; Match match = Regex.Match(rangeHeader, "^bytes ([\\d]+)-([\\d]+)\\/([\\d]+)$", RegexOptions.IgnoreCase); int bytesFrom = int.Parse(match.Groups[1].Value); int bytesTo = int.Parse(match.Groups[2].Value); int bytesFull = int.Parse(match.Groups[3].Value); if (bytesTo == bytesFull) model.IsLast = true; else model.IsLast = false; if (bytesFrom == 0) { model.ChunkNumber = 1; model.IsFirst = true; } else { int bytesSize = bytesTo - bytesFrom + 1; model.ChunkNumber = (bytesFrom / bytesSize) + 1; model.IsFirst = false; } } if (controllerContext.HttpContext.Request["HTTP_ACCEPT"] != null && controllerContext.HttpContext.Request["HTTP_ACCEPT"].Contains("application/json")) model.JsonAccepted = true; else model.JsonAccepted = false; return model; } }

and this is the controller action method:

public ActionResult Upload(UploadViewRequest request) { var path = ''; // create path FileStatus status = null; try { if (request.IsChunk) { if (request.IsFirst ) { // do some stuff that has to be done before the file starts uploading } var inputStream = request.OriginalFile.InputStream; using (var fs = new FileStream(path, FileMode.Append, FileAccess.Write)) { var buffer = new byte[1024]; var l = inputStream.Read(buffer, 0, 1024); while (l > 0) { fs.Write(buffer, 0, l); l = inputStream.Read(buffer, 0, 1024); } fs.Flush(); fs.Close(); } status = new FileStatus(new FileInfo(path)); if (request.IsLast) { // do some stuff that has to be done after the file is uploaded } } else { file.SaveAs(path); status = new FileStatus(new FileInfo(path)); } } catch { status = new FileStatus { error = "Something went wrong" }; } // this is just a browser json support/compatibility workaround if (request.JsonAccepted) return Json(status); else return Json(status, "text/plain"); }

The FileStatus class I use as a return value and transform it into json (for the UploadFile jquery module):

public class FileStatus { public const string HandlerPath = "/"; public string group { get; set; } public string name { get; set; } public string type { get; set; } public int size { get; set; } public string progress { get; set; } public string url { get; set; } public string thumbnail_url { get; set; } public string delete_url { get; set; } public string delete_type { get; set; } public string error { get; set; } public FileStatus() { } public FileStatus(FileInfo fileInfo) { SetValues(fileInfo.Name, (int)fileInfo.Length, fileInfo.FullName); } public FileStatus(string fileName, int fileLength, string fullPath) { SetValues(fileName, fileLength, fullPath); } private void SetValues(string fileName, int fileLength, string fullPath) { name = fileName; type = "image/png"; size = fileLength; progress = "1.0"; url = HandlerPath + "/file/upload?f=" + fileName; delete_url = HandlerPath + "/file/delete?f=" + fileName; delete_type = "DELETE"; thumbnail_url = "/Content/img/generalFile.png"; } }

更多推荐

本文发布于:2023-04-28 01:19:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1329223.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:上传文件   形式   MVC   Asp   Net

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!