[.NET][MVC]如何使用Ajax Helper傳送檔案

  • 953
  • 0
  • 2018-03-12

關於Ajax Helper的基本使用,

可以參考小弟之前寫的如何使用Ajax Helper


 

有鑑於公司突然有個case

需要使用Ajax傳送檔案到後端Parser

再吐model到前端

參考了網路許多作法

大部分都是使用jquery的ajax

回傳Json之後再去組前端

但我想了想...

 這樣就不能盡情使用MVC內建的Data Binding了阿!

於是我開始想方設法用MVC內建的Ajax將檔案傳送到後端(內建不支援)

有幸在stackoverflow尋獲大神的補帖

特此紀錄一下

 

後端部分其實跟一般操作表單傳送檔案沒有什麼差異

DemoController.cs

namespace AjaxPostFileDemo.Controllers
{
    public class DemoController : Controller
    {
        // GET: Demo
        public ActionResult Index()
        {
            return View();
        }


        public ActionResult AjaxPost()
        {
            return View();
        }

        [HttpPost]
        public ActionResult AjaxPost(HttpPostedFileBase attachment)
        {
            ViewData.Model = attachment.FileName;
            return View();
        }
    }
}

 

主要是前端的一段Script

Index.cshtml


@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

@using (Ajax.BeginForm("AjaxPost", null, new AjaxOptions
{
    UpdateTargetId = "ajaxTargetDiv"
}, new { enctype = "multipart/form-data" }))
{
    <div class="well">
        <div class="row">
            @Html.Label("選擇檔案", new { @class = "col-sm-2 control-label" })
            <div class="col-sm-10">
                <input type="file" name="attachment" class="form-control" />
            </div>
        </div>
        <div class="form-group row">
            <div class="col-sm-offset-8 col-sm-4">
                <button type="submit" class="btn btn-primary">送出</button>
            </div>
        </div>
    </div>
}

<div id="ajaxTargetDiv">
    @Html.Action("AjaxPost")
</div>

@section scripts{
    <script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
    <script>
        window.addEventListener("submit", function (e) {
            var form = e.target;
            if (form.getAttribute("enctype") === "multipart/form-data") {
                if (form.dataset.ajax) {
                    e.preventDefault();
                    e.stopImmediatePropagation();
                    var xhr = new XMLHttpRequest();
                    xhr.open(form.method, form.action);
                    xhr.onreadystatechange = function () {
                        if (xhr.readyState == 4 && xhr.status == 200) {
                            if (form.dataset.ajaxUpdate) {
                                var updateTarget = document.querySelector(form.dataset.ajaxUpdate);
                                if (updateTarget) {
                                    updateTarget.innerHTML = xhr.responseText;
                                }
                            }
                        }
                    };
                    xhr.send(new FormData(form));
                }
            }
        }, true);
    </script>
}

 

AjaxPost.cshtml

@model string

<div class="alert-danger ">
    你選擇的檔名是 @Model
</div>

 

實測結果如下圖

這種好用的東西

當然是快點打包成.js檔備著用啊!

-------------後記-------------

 

20180312

上次改完這段script之後

今天莫名其妙的又踩到雷了

想說來用AjaxOption裡面OnSuccess改個效果

結果發現Onxxxx的全都失效了(畢竟人家本來就不給你傳file阿...)

解法就是在updateTarget.innerHTML = xhr.responseText;下方多一個onComplete();

updateTarget.innerHTML = xhr.responseText;
onComplete();

 

恩...然後自己override一個onComplete

function onComplete(){
   alert("complete test!");
}