ASP.NET MVC+LayUI 视频上传
- 2025-10-29 广东
本文字数:5875 字
阅读完需:约 19 分钟
前言
前段时间在使用 APS.NET MVC+LayUI 做视频上传功能的时,发现当上传一些内存比较大的视频就会提示上传失败,后来通过查阅相关资料发现.NET MVC 框架为考虑安全问题,在运行时对请求的文件的长度(大小)做了限制默认为 4MB(4096KB),因此我们需要在 Web.Config 中设置最大请求文件长度大小,本文主要讲解如何设置 Web.Config 中的最大请求文件大小配置和提供一个完整的 ASP.NET MVC+LayUI 上传视频的教程。
上传内存较大视频提示异常
HTTP Error 404.13 - Not Found。
异常原因分析:
由上图我们可以清楚的知道因为我们所上传的视频内容藏毒超过了配置的值,所以上传失败了,并且还告诉我们需要到 web.config 文件中配置允许最大上传的文件长度。
设置 Web.config 文件中配置
到 Web.config 文件中的 httpRuntime 节点配置最大上传文件大小和 requestLimits 请求最大长度。
首先我们打开web.config=>找到system.web=>在httpRuntime中添加maxRequestLength属性值。
如下所示(maxRequestLength 和 maxAllowedContentLength 根据需求设置):
<system.web> <!--maxRequestLength:指示 ASP.NET 支持的最大文件上传大小。该限制可用于防止用户将大量未知的文件上传到应用服务器而导致不安全问题的发生。指定的大小以 KB 为单位。默认值为 4096 KB (4 MB)。--> <!--executionTimeout:表示允许执行请求的最大时间限制,单位为秒。--> <!--这里设置最大上传长度为200MB,执行超时时间为600s--> <httpRuntime targetFramework="4.7.2" maxRequestLength="204800" executionTimeout="600"/> <system.webServer> <security> <requestFiltering> <requestLimits maxAllowedContentLength="204800"/> </requestFiltering> </security> </system.webServer> </system.web>
httpRuntime 代码解释:
executionTimeout:表示允许执行请求的最大时间限制,单位为秒。maxRequestLength:指示 ASP.NET 支持的最大文件上载大小。该限制可用于防止因用户将大量文件传递到该服务器而导致的拒绝服务攻击。指定的大小以 KB 为单位。默认值为 4096 KB (4 MB)。useFullyQualifiedRedirectUrl:表示指示客户端重定向是否是完全限定(采用 "http://server/path" 格式,这是某些移动控件所必需的),或者指示是否代之以将相对重定向发送到客户端。如果为 True,则所有不是完全限定的重定向都将自动转换为完全限定的格式。false 是默认选项。minFreeThreads:表示指定允许执行新请求的自由线程的最小数目。ASP.NET 为要求附加线程来完成其处理的请求而使指定数目的线程保持自由状态。默认值为 8。minLocalRequestFreeThreads:表示ASP.NET 保持的允许执行新本地请求的自由线程的最小数目。该线程数目是为从本地主机传入的请求而保留的,以防某些请求在其处理期间发出对本地主机的子请求。这避免了可能的因递归重新进入 Web 服务器而导致的死锁。appRequestQueueLimit:表示ASP.NET 将为应用程序排队的请求的最大数目。当没有足够的自由线程来处理请求时,将对请求进行排队。当队列超出了该设置中指定的限制时,将通过“503 - 服务器太忙”错误信息拒绝传入的请求。enableVersionHeader:表示指定 ASP.NET 是否应输出版本标头。Microsoft Visual Studio 2005 使用该属性来确定当前使用的 ASP.NET 版本。对于生产环境,该属性不是必需的,可以禁用。
视频上传效果演示如下
前端使用 LayUI 的视频组件提交视频以二进制的文件格式提交到后端服务接口
1、首先引入相关的 layUI 相关的 js 和 css 文件包:
2、在页面中导入相关引用:
3、使用 layer.js 视频组件提交二进制文件到后端服务:
<link href="~/Content/layer-v3.1.1/layer/theme/default/layer.css" rel="stylesheet" /><link href="~/Content/layui-v2.4.5/css/layui.css" rel="stylesheet" />
<div class="jumbotron" style="margin-top: 200px;"> <h3><a href="https://www.cnblogs.com/Can-daydayup/">追逐时光者的ASP.NET MVC+LayUI视频上传教程</a></h3> <div class="row" style="margin-top: 20px;"> <div class="form-group znStyle"> <label class="col-sm-2 control-label"><em class="zent-form__required">*</em>视频上传:</label> <div class="col-sm-6"> <div id="upload_all_file"> <div class="layui-upload"> <button type="button" class="layui-btn" id="VideoBtn"><i class="layui-icon"></i>上传视频</button> <input type="hidden" name="Video" id="Video" /> <div class="layui-upload-list" id="videoPlay"> </div> </div> </div> </div> </div> </div></div>
<script src="~/Content/layer-v3.1.1/layer/layer.js"></script><script src="~/Content/layui-v2.4.5/layui.js"></script>
<!--layer.js视频上传--><script type="text/javascript"> var upload; //上传图片 layui.use('upload', function () { upload = layui.upload;
upload.render({ before: function () { layer.msg('视频努力上传中,请耐心等待...', { icon: 16, shade: 0.8, time: false }); }, elem: '#VideoBtn' , url: '@Url.Action("FileLoad","FileUpload")' , accept: 'video' //视频 , exts: 'mp4'//只允许上传的后缀(mp4文件) , done: function (res) { console.log(res); layer.closeAll(); layer.msg(res.msg); if (res.code == 1) { $("#Video").val(res.path); $("#videoPlay").html('<video controls="controls" id="currentVideo" style="width:400px;"><source src="' + res.path + '" type="video/mp4" /></video>'); $("#videoPlay").show(); // 自动播放 $("#currentVideo")[0].play(); } } });
$(".layui-upload-list").on("click", "i", function () { $(this).parent().remove(); }); });</script>
统一文件,图片,视频,音频上传服务(FileUploadController):
using System;using System.IO;using System.Text;using System.Web;using System.Web.Mvc;
namespace VideoUpload.Controllers{ /// <summary> /// 文件,图片,视频,音频统一上传服务 /// </summary> public class FileUploadController : Controller { /// <summary> /// 对验证和处理 HTML 窗体中的输入数据所需的信息进行封装,如FromData拼接而成的文件[图片,视频,文档等文件上传] /// </summary> /// <param name="context">FemContext对验证和处理html窗体中输入的数据进行封装</param> /// <returns></returns> [AcceptVerbs(HttpVerbs.Post)] public ActionResult FileLoad(FormContext context)//FemContext对验证和处理html窗体中输入的数据进行封装 {
HttpPostedFileBase httpPostedFileBase = Request.Files[0];//获取文件流 if (httpPostedFileBase != null) { try { ControllerContext.HttpContext.Request.ContentEncoding = Encoding.GetEncoding("UTF-8"); ControllerContext.HttpContext.Response.Charset = "UTF-8";
string fileName = Path.GetFileName(httpPostedFileBase.FileName);//原始文件名称 string fileExtension = Path.GetExtension(fileName);//文件扩展名
byte[] fileData = ReadFileBytes(httpPostedFileBase);//文件流转化为二进制字节
string result = SaveFile(fileExtension, fileData);//文件保存 return string.IsNullOrEmpty(result) ? Json(new { code = 0, path = "", msg = "网络异常,文件上传失败~" }) : Json(new { code = 1, path = result, msg = "文件上传成功" }); } catch (Exception ex) { return Json(new { code = 0, msg = ex.Message, path = "" }); } } else { return Json(new { code = 0, path = "", msg = "网络异常,文件上传失败~" }); } }
/// <summary> /// 将文件流转化为二进制字节 /// </summary> /// <param name="fileData">图片文件流</param> /// <returns></returns> private byte[] ReadFileBytes(HttpPostedFileBase fileData) { byte[] data; using (var inputStream = fileData.InputStream) { if (!(inputStream is MemoryStream memoryStream)) { memoryStream = new MemoryStream(); inputStream.CopyTo(memoryStream); } data = memoryStream.ToArray(); } return data; }
/// <summary> /// 保存文件 /// </summary> /// <param name="fileExtension">文件扩展名</param> /// <param name="fileData">图片二进制文件信息</param> /// <returns></returns> private string SaveFile(string fileExtension, byte[] fileData) { string result; string saveName = Guid.NewGuid().ToString() + fileExtension; //保存文件名称 string basePath = "UploadFile"; string saveDir = DateTime.Now.ToString("yyyy-MM-dd");
// 文件上传后的保存路径 string serverDir = Path.Combine(Server.MapPath("~/"), basePath, saveDir);
string fileNme = Path.Combine(serverDir, saveName);//保存文件完整路径 try { var savePath = Path.Combine(saveDir, saveName);
//项目中是否存在文件夹,不存在创建 if (!Directory.Exists(serverDir)) { Directory.CreateDirectory(serverDir); }
System.IO.File.WriteAllBytes(fileNme, fileData);//WriteAllBytes创建一个新的文件,按照对应的文件流写入,假如已存在则覆盖
//返回前端项目文件地址 result = "/" + basePath + "/" + saveDir + "/" + saveName; } catch (Exception ex) { result = "发生错误" + ex.Message; } return result; }
}}
参考文章
https://docs.microsoft.com/en-us/iis/configuration/system.webServer/security/requestFiltering/requestLimits
http://www.webkaka.com/tutorial/asp.net/2018/051026
源码地址
https://github.com/YSGStudyHards/VideoUpload
版权声明: 本文为 InfoQ 作者【追逐时光者】的原创文章。
原文链接:【http://xie.infoq.cn/article/ff795a1b3a0ac95027d057d44】。文章转载请联系作者。
追逐时光者
不积跬步无以至千里,不积小流无以成江海! 2020-01-14 加入
微软MVP、华为云HCDE、华为云云享专家、51CTO专家博主、阿里云专家博主、博客园推荐博客、CSDN博客专家、腾讯云创作之星、掘金优秀创作者,一个热爱开源的全栈软件工程师,擅长C#、.NET、Vue等相关技术开发。







评论