[WEB API]使用vue和axios來上傳檔案到web api

EB API]使用vue和axios來上傳檔案到web api

前言

早期都是使用控制項,然後四處google來實做web api上傳的範例,但是每做一次就要google一次,這次決定用最原始的方式來實做,不依賴於第三方的package,只使用原始的html5來實做,其實這邊根本沒什麼用到vue的功能,因為上傳其實跟vue也沒什麼太大的關係,用什麼技術都是一樣的。

動手實做

首先看一下html和javascript的部份

<body>
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <div id="app">
    <input type="file" @change="fileChange">
    <button @click="upload">upload</button>
  </div>
  <script>
    let app = new Vue({
      el: '#app',
      data: {
        formData: new FormData() //因為我這邊沒有使用form,所以就自行new了一個FormData
      },
      methods: {
        fileChange(e) {
            this.formData.append('file', e.target.files[0]) //放進上傳的檔案
        },
        upload() {
          axios.post('http://localhost:11084/api/value/', this.formData)
        }
      }
    })
  </script>
</body>

在來看一下web api的部份,其實也很單純,沒什麼很大特別的地方

    public class ValueController : ApiController
    {
        public async Task<IHttpActionResult> Post()
        {
            if (!Request.Content.IsMimeMultipartContent())
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }

            var provider = new MultipartMemoryStreamProvider();
            await Request.Content.ReadAsMultipartAsync(provider);
            var path =HttpContext.Current.Server.MapPath("~/Upload");
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            foreach (var file in provider.Contents)
            {
                var fileName = file.Headers.ContentDisposition.FileName.Trim('\"'); //從header去取得filename的名字
                var fullPath = File.Create($"{path}/{fileName}");
                var buffer = await file.ReadAsByteArrayAsync();
                await fullPath.WriteAsync(buffer, 0, buffer.Length);
            }

            return Ok();
        }
    }

上傳測試成功無誤,但是如果我們這次想要改成多筆一起上傳呢,請再次看一下前端的部份

<body>
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <div id="app">
    <!--改成multiple以便多筆一起上傳-->
    <input multiple type="file" @change="fileChange">
    <button @click="upload">upload</button>
  </div>
  <script>
    let app = new Vue({
      el: '#app',
      data: {
        formData: new FormData() //因為我這邊沒有使用form,所以就自行new了一個FormData
      },
      methods: {
        fileChange(e) {
          for (var i = 0; i < e.target.files.length; i++) {
            this.formData.append('file', e.target.files[i]) //用迴圈抓出多少筆再append回來
          }
        },
        upload() {
          axios.post('http://localhost:11084/api/value/', this.formData)
        }
      }
    })
  </script>
</body>

web api基本上不用變動,但是當我選擇要上傳的檔案,卻發生了錯誤"{message: "An error has occurred.", exceptionMessage: "超出最大的要求長度。",…}"

這個訊息好像太明確了,也就是我們上傳的檔案超過大小了,那最簡單的方式就是在web.config設置就好了。

<httpRuntime targetFramework="4.6.1" maxRequestLength="10240" executionTimeout="300"/> 
<!--加上maxRequestLength為10M,執行時間則為300秒-->

結論

很簡單的完成了這個example,很多網路上的文章都是談web form或mvc的,或者是一些jquery的plugin,不過即然我使用vue和axios了,自然就是要搭配web api的方式,如果有任何錯誤的話,再請給予建議給筆者。