如何使用multipart/form-data执行ASP.NET MVC Ajax表单帖子?

dsw*_*tik 24 html asp.net asp.net-mvc

我正在开发一个ASP.NET MVC网站,该网站的表单允许使用表单标签上的multipart/form data enctype选项上传文件,如此

<form enctype="multipart/form-data" method="post" action='<%= Url.Action("Post","Entries",new {id=ViewData.Model.MemberDetermination.DeterminationMemberID})  %>'>
Run Code Online (Sandbox Code Playgroud)

我怎么写这个来做一个ASP.NET MVC Ajax表单帖子呢?

Dem*_*ius 34

这是可能的,但这是一个漫长的道路.第1步:写下您的表单

例如:

@using (Ajax.BeginForm(YourMethod, YourController, new { id= Model.Id }, new AjaxOptions {//needed options }, new { enctype = "multipart/form-data" }))
{
    <input type="file" id="image" name="image" />
    <input type="submit" value="Modify" />
}
Run Code Online (Sandbox Code Playgroud)

第2步:拦截请求并将其发送到服务器

<script type="text/javascript">
    $(function() {
        $("#form0").submit(function(event) {
            var dataString;
            event.preventDefault();
            var action = $("#form0").attr("action");
            if ($("#form0").attr("enctype") == "multipart/form-data") {
                //this only works in some browsers.
                //purpose? to submit files over ajax. because screw iframes.
                //also, we need to call .get(0) on the jQuery element to turn it into a regular DOM element so that FormData can use it.
                dataString = new FormData($("#form0").get(0));
                contentType = false;
                processData = false;
            } else {
                // regular form, do your own thing if you need it
            }
            $.ajax({
                type: "POST",
                url: action,
                data: dataString,
                dataType: "json", //change to your own, else read my note above on enabling the JsonValueProviderFactory in MVC
                contentType: contentType,
                processData: processData,
                success: function(data) {
                    //BTW, data is one of the worst names you can make for a variable
                    //handleSuccessFunctionHERE(data);
                },
                error: function(jqXHR, textStatus, errorThrown) {
                    //do your own thing
                    alert("fail");
                }
            });
        }); //end .submit()
    });
</script>
Run Code Online (Sandbox Code Playgroud)

第3步:因为您进行了ajax调用,所以您可能想要替换某些图像或其他内容 multipart/form-data

例如:

handleSuccessFunctionHERE(data)
{
    $.ajax({
        type: "GET",
        url: "/Profile/GetImageModified",
        data: {},
        dataType: "text",
        success: function (MSG) {
            $("#imageUploaded").attr("src", "data:image/gif;base64,"+msg);
        },
        error: function (msg) {
            alert(msg);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

MSG变量是base64加密字符串.就我而言,它是图像的来源.

通过这种方式,我设法更改了个人资料图片,之后图片立即更新.另外请确保添加Application_Start(global.asax)非常 ValueProviderFactories.Factories.Add(new JsonValueProviderFactory()); 好吗?

PS:此解决方案有效,请不要犹豫,询问更多细节.

  • 添加event.stopPropagation(); 防止它提交两次. (2认同)
  • [HttpPost] public ActionResult YourAction(HttpPostedFileBase file) { /*save file here */ return RedirectToAction(YourAction); } (2认同)

Jam*_*ton 33

我遇到了这个小黑客,很好地解决了这个问题

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);
Run Code Online (Sandbox Code Playgroud)


zih*_*tki 6

  1. 你可以使用一些额外的上传器(例如jQuery多文件上传器)(我更喜欢这种方式,我更喜欢不使用MS Ajax)
  2. 使用:

    AjaxHelper.BeginForm("Post", "Entries", new {id=ViewData.Model.MemberDetermination.DeterminationMemberID}, new AjaxOptions(){/*some options*/}, new {enctype="multipart/form-data"})
    
    Run Code Online (Sandbox Code Playgroud)

但在第二种情况下,我不确定它会起作用.

  • 是的请dswatik发布一个例子,因为一切都很好,但我没有在服务器上收到任何图像文件! (4认同)
  • 是的,也没有文件发送到服务器. (4认同)
  • @dswatik - 你能发一个#2的例子吗?我试过了,但无法让它发挥作用. (3认同)
  • 可以确认第二个例子不起作用...... :( (3认同)
  • 实际上,您的选项 2 有效..我在这里遇到了另一个类似的问题,但使用普通的 beginform 而不是 ajax beginform 助手......使用新的 enctype 对象,所以我想我会尝试一下并且它有效.. (2认同)

Kar*_*man 5

我使用的代码可以正常工作!它是@James'Fluffy'Burton解决方案的副本。我只是即兴回答他的问题,以便对MVC陌生的人能够快速理解后果。

以下是我的观点:

@using (Ajax.BeginForm("FileUploader", null, new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "AjaxUpdatePanel" }, new { enctype = "multipart/form-data", id = "frmUploader" })){
<div id="AjaxUpdatePanel">     
    <div class="form-group">
        <input type="file" id="dataFile" name="upload" />
    </div>

    <div class="form-group">
        <input type="submit" value="Upload" class="btn btn-default" id="btnUpload"/>
    </div>

</div>}

<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);
Run Code Online (Sandbox Code Playgroud)

以下是我的控制器:

[HttpPost]
    public JsonResult FileUploader(HttpPostedFileBase upload)
    {
        if (ModelState.IsValid)
        {
            if (upload != null && upload.ContentLength > 0)
            {

                if (upload.FileName.EndsWith(".csv"))
                {
                    Stream stream = upload.InputStream;
                    DataTable csvTable = new DataTable();
                    using (CsvReader csvReader = new CsvReader(new StreamReader(stream), true))
                    {
                        csvTable.Load(csvReader);
                    }
                }
                else
                {
                    return Json(new { dataerror = true, errormsg = "This file format is not supported" });
                }
            }
            else
            {
                return Json(new { dataerror = true, errormsg = "Please Upload Your file" });
            }
        }
        return Json(new { result = true });
    }
Run Code Online (Sandbox Code Playgroud)

以下是上面代码的快速注释:通过Ajax,我将excel(* .csv)文件发布到了Server,并使用Nuget包(LumenWorksCsvReader)将其读取到DataTable中。

欢呼!有用。谢谢@詹姆斯