2016年3月9日 星期三

[MVC] Upload file template

 Upload File    MVC





Introduction


This article will introduce how to implement Upload file function with MVC and System.Web.HttpPostedFileBase.


Related article


Environment

l   Visual Studio 2015 Ent.



Implement


ViewModel

public class VmFile
    {
        public string FileName { get; set; }
        public HttpPostedFileBase FileBase { get; set; }
    }

public class VmDownloadFile
    {
        public string FileName { get; set; }
        public string Uri { get; set; }
    }


View

l   Upload

@model JB.Sample.FileUpload.Website.Models.VmFile

@using (Html.BeginForm("Index", "File", System.Web.Mvc.FormMethod.Post, new { enctype = "multipart/form-data" }))
{
     <input type="file" id="FileBase" name="FileBase" style="margin-top:5px;">
     <input type="submit" value="Upload" class="btn btn-default" />
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}


這邊的重點在於HTML file input的名稱必須和View Modelproperty name 相同, 這樣在POST才會正確rendorView Model


l   Query and download

@model IEnumerable<JB.Sample.FileUpload.Website.Models.VmDownloadFile>
@foreach (var item in Model)
{
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.FileName)
        </td>
        <td>
            @{
                string applicationUri = Url.Content(string.Concat("~/Upload/", item.FileName));
            }
            <a href="@applicationUri">
                <img style="width:15px;height:15px" src="~/Content/Images/file.jpg" />
            </a>
        </td>
    </tr>
}

</table>



Controller


l   Upload action

private static string SAVED_FILES_PATH = "~/Upload/";

// GET: File/Create
 [HttpPost]
public ActionResult Index(VmUploadFile viewModel)
{
            //Validations
            if (!this.validateViewModel())
            {
                return View(viewModel);
            }

            string fileExtension = string.Empty;
            int maxContentLength = 1024 * 1024 * 10; //max bit = 10 MB
            string[] allowedFileExtensions = new string[] { ".pdf" }; //File extensions contraints

            if (viewModel.FileBase != null)
            {
                if (viewModel.FileBase.ContentLength > 0)
                {
                    #region Validation

                    fileExtension = System.IO.Path.GetExtension(viewModel.FileBase.FileName);
                    if (!allowedFileExtensions.Contains(fileExtension))
                    {
                        ModelState.AddModelError("DownloadFilesError", "檔案類型不符合規定,允許上傳的格式: " + string.Join(", ", allowedFileExtensions));
                        return View(viewModel);
                    }
                    else if (viewModel.FileBase.ContentLength > maxContentLength)
                    {
                        ModelState.AddModelError("DownloadFilesError", "檔案大小超過限制,檔案大小限制為: " + (maxContentLength / 1024 / 1024) + " MB");
                        return View(viewModel);
                    }

                    #endregion

                    #region Rename (Not neccessary)

                    if (string.IsNullOrEmpty(viewModel.FileName))
                    {
                        Guid id = Guid.NewGuid();
                        viewModel.FileName = $"{id}_{DateTime.Now.ToString("yyyyMMdd")}{fileExtension}";
                    }

                    #endregion

                    #region The callback of duplicated file name - Delete it.

                    string fullPath = Request.MapPath(SAVED_FILES_PATH + viewModel.FileName);
                    if (System.IO.File.Exists(fullPath))
                    {
                        System.IO.File.Delete(fullPath);
                    }

                    #endregion

                    #region Save it to the server side

                    var physicalPath = Path.Combine(Server.MapPath("~/Upload/"), viewModel.FileName);
                    viewModel.FileBase.SaveAs(physicalPath);

                    #endregion
                }
            }

            return RedirectToAction("Download");
}



l   Download action

public ActionResult Download()
{
            #region Get all downloadabled files on server
            var downloadFiles = getAllFiles();
            #endregion

            return View(downloadFiles);
}



private IEnumerable<VmDownloadFile> getAllFiles()
{
            List<VmDownloadFile> downloadFiles = new List<VmDownloadFile>();
            string filepath = Server.MapPath(SAVED_FILES_PATH);
            DirectoryInfo d = new DirectoryInfo(filepath);

            foreach (var file in d.GetFiles("*.pdf"))
            {
                downloadFiles.Add(new VmDownloadFile()
                {
                    FileName = file.Name,
                    Uri = Path.Combine(SAVED_FILES_PATH, file.Name)
                });
            }

            return downloadFiles;
}



Results















Reference




沒有留言:

張貼留言