• MVC中的文件上传-小结


    web开发中,文件的上传是非常基本功能之一。
    在asp.net中,通常做法是利用webservice 来接收文件请求,这样做的好处就是全站有了一个统一的文件上传接口,并且根据网站的实际情况,可以将webservice部署到其他服务器上,可以兼容考虑将来的分布存储等等问题。
     
    在MVC中实现文件上传主要有2中方式:
    1.普通Controller实现文件上传
    2.ApiController实现文件上传
     

    普通Controller实现文件上传

    在普通的Controller中实现文件上传时,需要使用到HttpPostedFileBase类 来接收文件。调用HttpPostedFileBase 实例对象的SaveAs()方法,就可以将文件保存在服务器中,示例代码如下:
    HTML片段:
    <h2>Upload</h2>
    @using (Html.BeginForm("Upload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
    {
        <div>
            <h4>Select a file:</h4>
            <input name="files" id="files" type="file" />
            <label id="lbError">@ViewBag.ErrorMessage</label>
            <input type="submit" name="submit" value="Upload" />
        </div>
    }

     

    Controller中的Action片段:
    [HttpPost]
    public ActionResult Upload(IEnumerable<HttpPostedFileBase> files)
    {
        if (files == null || files.Count() == 0 || files.ToList()[0] == null)
        {
            ViewBag.ErrorMessage = "Please select a file!!";
            return View();
        }
        string filePath = string.Empty;
        Guid gid = Guid.NewGuid();
        foreach (HttpPostedFileBase file in files)
        {
            filePath = Path.Combine(HttpContext.Server.MapPath("/Uploads/"), gid.ToString() + Path.GetExtension(file.FileName));
            file.SaveAs(filePath);
        }
        return RedirectToAction("UploadResult", new { filePath = filePath });
    }
    public ActionResult UploadResult(string filePath)
    {
        ViewBag.FilePath = filePath;
        return View();
    }
    需要注意2个问题:
    1. 注意给form表单加上enctype = "multipart/form-data" 属性,否则会导致Action的参数HttpPostedFileBase 对象接收不到文件。
    2. 注意文件大小,IIS中默认上传的文件大小为4MB ,超过这大小的文件需要在修改配置文件。
     
    上传大文件时修改文件大小限制如下:
    第一步:asp.net中的文件大小限制
    <system.web>
        <httpRuntime maxRequestLength="153600" executionTimeout="900" />
    </system.web>
    第二步:IIS中文件大小限制
    <system.webServer>
        <security>
            <requestFiltering>
                    <requestLimits maxAllowedContentLength="157286400" />
                 </requestFiltering>
        </security>
    </system.webServer>

     

    ApiController实现文件上传

    通过ApiController来实现文件上传时,不得不参考一下 官方文档了,建议先去阅读一下。

    我自己在实现Demo时, 开发环境为.net 4.0。
    HTML片段:
    <h2>API Upload</h2>
    <form name="apiForm" method="post" enctype="multipart/form-data" action="/api/upload">
        <div>
            <label for="apifiles">Select a File</label>
            <input name="apifiles" type="file" />
        </div>
        <div>
            <input type="submit" value="Upload" />
        </div>
    </form>
    ApiController代码:
    public class UploadController : ApiController
        {
            public Task<HttpResponseMessage> PostFormData()
            {
                if (!Request.Content.IsMimeMultipartContent())
                {
                    throw new Exception("");
                }
                string root = HttpContext.Current.Server.MapPath("/Uploads/");
                var provider = new ReNameMultipartFormDataStreamProvider(root);
     
                var task = Request.Content.ReadAsMultipartAsync(provider).ContinueWith<HttpResponseMessage>(t =>
                {
                    if (t.IsFaulted || t.IsCanceled)
                    {
                        Request.CreateErrorResponse(HttpStatusCode.InternalServerError, t.Exception);
                    }
                    string fileName = string.Empty;
                    foreach (MultipartFileData file in provider.FileData)
                    {
                        fileName = file.LocalFileName;
                    }
                    //返回上传后的文件全路径
                    return new HttpResponseMessage() { Content = new StringContent(fileName) };
                });
                return task;
            }
        }
     
        /// <summary>
        /// 重命名上传的文件
        /// </summary>
        public class ReNameMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
        {
            public ReNameMultipartFormDataStreamProvider(string root)
                : base(root)
            { }
     
            public override string GetLocalFileName(System.Net.Http.Headers.HttpContentHeaders headers)
            {
                //截取文件扩展名
                string exp = Path.GetExtension(headers.ContentDisposition.FileName.TrimStart('"').TrimEnd('"'));
                string name = base.GetLocalFileName(headers);
                return name + exp;
            }
     
        }

    如上代码,区别与官网给出的.net 4.0 版本的代码的。

    请注意: ReNameMultipartFormDataStreamProvider  为自定义类,继承自MultipartFormDataStreamProvider, 这个累的目的就是对上传上来的文件在保存到服务器时,保留文件的扩展名。MultipartFormDataStreamProvider类默认保存的文件是没有扩展名称的。当然我自己这里实现的方式的确挺土的,演示Demo明白思议即可,呵呵。
     
    到这里就差不多了,后面准备实现Ajax+SingR来实现文件上传时显示上传进度的Demo。
     
    参考资料:
     
    Confusing required maxRequestLength and maxAllowedContentLength settings
     
    关于MVC4.0 WebAPI上传图片重命名以及图文结合
     
    ASP.NET Web Api Self Host大文件上传功能
     
     
     
     
  • 相关阅读:
    从OkHttp的源码来看 HTTP
    从Retrofit的源码来看 HTTP
    登录授权、TCP/IP、HTTPS
    编码、加密、Hash
    java获取当前系统时间
    mybatis自动生成
    rabbitMQ权限相关命令
    在Spring Boot中使用Spring Security实现权限控制
    学习sharding-jdbc 分库分表扩展框架
    Jenkins的关闭、重启
  • 原文地址:https://www.cnblogs.com/kids/p/uploadfile.html
Copyright © 2020-2023  润新知