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大文件上傳功能
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM