ASP.NET Core 1.0中实现文件上传的两种方式(提交表单和采用AJAX)

Bipin Joshi (http://www.binaryintellect.net/articles/f1cee257-378a-42c1-9f2f-075a3aed1d98.aspx)

Uploading files is a common requirement in web applications. In ASP.NET Core 1.0 uploading files and saving them on the server is quite easy. To that end this article shows how to do just that.Begin by creating a new ASP.NET Core project. Then add HomeController to the controllers folder. Then add UploadFiles view to Views > Home folder of the application.

HTML form for uploading files

Open the UploadFiles view and add the following HTML markup in it:

   1: <form asp-action="UploadFiles" 
   2:       asp-controller="Home" 
   3:       method="post"
   4:       enctype="multipart/form-data">
   5:     <input type="file" name="files" multiple />
   6:     <input type="submit" value="Upload Selected Files" />
   7: </form>

The above markup uses form tag helper of ASP.NET Core MVC. The asp-action attribute indicates that the form will be processed by the UploadFiles action upon submission. The asp-controller attribute specifies the name of the controller containing the action method. The form is submitted using POST method. The enctype attribute of the form is set to multipart/form-data indicating that it will be used for file upload operation.

The form contains an input field of type file. The name attribute of the file input field is set to files and the presence of multiple attribute indicates that multiple files can be uploaded at once. The submit button submits the form to the server.

If you run the application at this stage, the UploadFiles view should look like this:

Constructor and UploadFiles() GET action

Now, open the HomeController and add a constructor to it as shown below:

   1: public class HomeController : Controller
   2: {
   3:     private IHostingEnvironment hostingEnv;
   4:     public HomeController(IHostingEnvironment env)
   5:     {
   6:         this.hostingEnv = env;
   7:     }
   8: }

The constructor has a parameter of type IHostingEnvironment (Microsoft.AspNet.Hosting namespace). This parameter will be injected by MVC framework into the constructor. You need this parameter to construct the full path for saving the uploaded files. The IHostingEnvironment object is saved into a local variable for later use.

Then add UploadFiles() action for GET requests as shown below:

   1: public IActionResult UploadFiles()
   2: {
   3:     return View();
   4: }

UploadFiles() POST action

Finally, add UploadFiles() action for handling the POST requests.

   1: [HttpPost]
   2: public IActionResult UploadFiles(IList<IFormFile> files)
   3: {
   4:     long size = 0;
   5:     foreach(var file in files)
   6:     {
   7:         var filename = ContentDispositionHeaderValue
   8:                         .Parse(file.ContentDisposition)
   9:                         .FileName
  10:                         .Trim('"');
  11:         filename = hostingEnv.WebRootPath + $@"\{fileName}";
  12:         size += file.Length;
  13:         using (FileStream fs = System.IO.File.Create(filename))
  14:         {
  15:            file.CopyTo(fs);
  16:            fs.Flush();
  17:         }
  18:     }
  19:  
  20:     ViewBag.Message = $"{files.Count} file(s) / 
  21:                       {size} bytes uploaded successfully!";
  22:     return View();
  23: }

The UploadFiles() action has a parameter - IList<IFormFile> - to receive the uploaded files. The IFormFile object represents a single uploaded file. Inside, a size variable keeps track of how much data is being uploaded. Then a foreach loop iterates through the files collection.

The client side file name of an uploaded file is extracted using the ContentDispositionHeaderValue class (Microsoft.Net.Http.Headers namespace) and the ContentDisposition property of the IFormFile object. Let's assume that you wish to save the uploaded files into the wwwroot folder. So, to arrive at the full path you use the WebRootPath property of IHostingEnvironment and append the filename to it.

Finally, the file is saved by the code inside the using block. That code basically creates a new FileStream and copies the uploaded file into it. This is done using the Create() and the CopyTo() methods. A message is stored in ViewBag to be displayed to the end user.

The following figure shows a sample successful run of the application:

Using jQuery Ajax to upload the files

In the preceding example you used form POST to submit the files to the server. What if you wish to send files through Ajax? You can accomplish the task with a little bit of change to the <form> and the action.

Modify the <form> to have a plain push button instead of submit button as shown below:

   1: <form method="post" enctype="multipart/form-data">
   2:     <input type="file" id="files" 
   3:            name="files" multiple />
   4:     <input type="button" 
   5:            id="upload" 
   6:            value="Upload Selected Files" />
   7: </form>

Then add a <script> reference to the jQuery library and write the following code to handle the click event of the upload button:

   1: $(document).ready(function () {
   2:     $("#upload").click(function (evt) {
   3:         var fileUpload = $("#files").get(0);
   4:         var files = fileUpload.files;
   5:         var data = new FormData();
   6:         for (var i = 0; i < files.length ; i++) {
   7:             data.append(files[i].name, files[i]);
   8:         }
   9:         $.ajax({
  10:             type: "POST",
  11:             url: "/home/UploadFilesAjax",
  12:             contentType: false,
  13:             processData: false,
  14:             data: data,
  15:             success: function (message) {
  16:                 alert(message);
  17:             },
  18:             error: function () {
  19:                 alert("There was error uploading files!");
  20:             }
  21:         });
  22:     });
  23: });

The above code grabs each file from the file field and adds it to a FormData object (HTML5 feature). Then $.ajax() method POSTs the FormData object to the UploadFilesAjax() action of the HomeController. Notice that the contentType and processData properties are set to false since the FormData contains multipart/form-data content. The data property holds the FormData object.

Finally, add UploadFilesAjax() action as follows:

   1: [HttpPost]
   2: public IActionResult UploadFilesAjax()
   3: {
   4:     long size = 0;
   5:     var files = Request.Form.Files;
   6:     foreach (var file in files)
   7:     {
   8:         var filename = ContentDispositionHeaderValue
   9:                         .Parse(file.ContentDisposition)
  10:                         .FileName
  11:                         .Trim('"');
  12:         filename = hostingEnv.WebRootPath + $@"\{filename}";
  13:         size += file.Length;
  14:         using (FileStream fs = System.IO.File.Create(filename))
  15:         {
  16:            file.CopyTo(fs);
  17:            fs.Flush();
  18:         }
  19:     }
  20:     string message = $"{files.Count} file(s) / 
  21:                        {size} bytes uploaded successfully!";
  22:     return Json(message);
  23: }

The code inside UploadFilesAjax() is quite similar to UploadFiles() you wrote earlier. The main difference is how the files are received. The UploadFilesAjax() doesn't have IList<IFormFile> parameter. Instead it receives the files through the Request.Form.Files property. Secondly, the UploadFilesAjax() action returns a JSON string message to the caller for the sake of displaying in the browser.

That's it for now! Keep coding!!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏everhad

转载:Package by feature, not layer

The first question in building an application is "How do I divide it up into pac...

1340
来自专栏耕耘实录

国外程序员推荐的免费编程书籍资源

我正试着搜集整理一个可在网上免费阅读的计算机编程书籍列表。这些书可以是某种特定编程语言,也可以计算机方面通用书籍。网上有哪些免费可用的书籍呢?

3644
来自专栏.NET开发那点事

Async方法死锁的问题 Don't Block on Async Code(转)

今天调试requet.GetRequestStreamAsync异步方法出现不返回的问题,可能是死锁了。看到老外一篇文章解释了异步方法死锁的问题,懒的翻译,直接...

1130
来自专栏张善友的专栏

Line Counter - Writing a Visual Studio 2005 Add-In

Download original source files - 553 Kb Download new source files - 1483 Kb Do...

2098
来自专栏技术小黑屋

Build Android Packages From Command Line

A few months ago,I dealed with a task:To build a large amount of apk files. The...

1253
来自专栏Golang语言社区

Go调试简单的内存泄漏

Memory leaks are a class of bugs where memory is not released even after it is n...

4883
来自专栏技术小黑屋

Package Stopped State Since Android 3.1

Since Android 3.1, Android has introduced a LaunchControl mechanism. It’s call S...

1011
来自专栏Golang语言社区

Knapsack problem algorithms for my real-life carry-on knapsack

I'm a nomad and live out of one carry-on bag. This means that the total weight o...

1432
来自专栏程序员笔记

Note_Motivation & Gamification

2266
来自专栏Albert陈凯

2018-11-06 openhub.net开源项目。

1442

扫码关注云+社区

领取腾讯云代金券