Ajax样式上传等同于XmlHttpRequest文件上传到MVC控制器?通过ajax上传到MVC控制器解决了

时间:2014-04-11 13:26:53

标签: jquery ajax asp.net-mvc asp.net-mvc-4 asp.net-ajax

现在我在页面上有多个表单,我想要删除它。所以目前我正在这样做。

JAVASCRIPT

  $("button[id$='uploadfile']").click(function (evt) {
        //////////////////////////////////////////////////////
        // This code block works
        alert("upload file");
        var file1 = $('#csvIdentifierFileBase').val();
        var formData = new FormData();
        var opmlFile = $('#csvIdentifierFileBase')[0];
        formData.append("opmlFile", opmlFile.files[0]);
        var xhr = new XMLHttpRequest();
        xhr.open('POST', 'alt/Import');
        xhr.send(formData);
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4 && xhr.status == 200) {
                alert(xhr.responseText);
            }
        };
        //////////////////////////////////////////////////////

        //////////////////////////////////////////////////////
        // This code block does not
        $.ajax({
            type: 'POST',
            url: 'alt/Import',
            data: formData,
            enctype: 'multipart/form-data',
            //cache: false,
            //contentType: false,
            //processData: false,
            success: function (result) {
                alert(result.success);
            },
            error: function (a, b, c) {
                alert("An error has occurred.");
            }
        });

HTML

        <div class="col-md-12">
            <input type="file" name="csvIdentifierFileBase" id="csvIdentifierFileBase"/>
            <button id="uploadfile" name="action" value="Import" >Import</button>
        </div>

CONTROLLER

    [System.Web.Http.HttpPost]
    public ActionResult Import()//HttpPostedFileBase csvIdentifierFileBase)
    {
        HttpResponseMessage result = null;
        HttpPostedFileBase file = Request.Files[0]; //Uploaded file
    }

除了对这个控制器方法的javscript调用之外没有改变任何东西,并且使用XmlHttpRequest它工作正常,有没有办法切换到jquery / ajax样式调用所以我不依赖于XmlHttpRequest对象并仍然拥有它打电话到控制器?我正在寻找原生解决方案而不是其他类型的插件......这可能吗? 也无法将输入和按钮包装在AJAX.BeginForm标记中,因为我试图消除一页上的表单数量。

1 个答案:

答案 0 :(得分:1)

希望这会帮助其他人,因为我花了很多时间在这上面。以下是如何通过$ .ajax发布文件,没有任何其他插件,并且在html视图中没有Ajax.BeginForm标记。

<强> JAVASCRIPT

    $("button[id$='uploadfile']").click(function (evt) {
    alert("upload file");
    // relatively irrelevant name used here but is not what model binder uses in MVC
    var file_data = $("#csvIdentifierFileBase").prop("files")[0];   // Getting the properties of file from file field
    var form_data = new FormData();                  // Creating object of FormData class
    // THIS IS IMPORTANT, THE NAME HERE **"file"** IS WHAT THE MODEL BINDER USES IN MVC CONTROLLER
    form_data.append("file", file_data);            // Appending parameter named file with properties of file_field to form_data
    //form_data.append("user_id", 123);             // Adding extra parameters to form_data
    $.ajax({
        url: "alt/Import",
        dataType: 'script',
        cache: false,
        contentType: false,
        processData: false,
        data: form_data,                            // Setting the data attribute of ajax with file_data
        type: 'post'
    });
});

HTML 没有形式标签没有插件

         // name and id of input type file relatively irrelevant 
        <div class="col-md-12">
            <input type="file" name="csvIdentifierFileBase" id="csvIdentifierFileBase"/>
            <button id="uploadfile" name="action" value="Import" >Import</button>
        </div>

<强> CONTROLLER

    [System.Web.Http.HttpPost]
    public ActionResult Import(HttpPostedFileBase file) // THIS VAIRABLE NAME HAS TO BE THE SAME AS WHAT IS PASSED IN VIA THE SCRIPT FOR FORM DATA
    {
        HttpResponseMessage result = null;
        HttpPostedFileBase file = Request.Files[0]; //Uploaded file JUST A SECOND WAY TO ACCESS THE SAME INFORMATION THAT IS COMING IN AS HttpPostedFileBase file
    }

但是这里是GIT IE中不支持FormData(),因此这种方法不适用于IE

支持信息可在此处找到 http://blog.w3villa.com/websites/uploading-filesimage-with-ajax-jquery-without-submitting-a-form/

IE替代

<强> HTML

        <div class="col-md-12">
            <input type="file" name="csvIdentifierFileBase" id="csvIdentifierFileBase"/>
            <button id="uploadfile" name="action" value="Import" >Import</button>
        </div>

<强> JAVASCRIPT

$("button[id$='uploadfile']").click(function (evt) {
    evt.preventDefault();
    var $newForm = $('<form>', {
        'action': 'alt/Import',
        'method': 'post',
        'enctype': 'multipart/form-data',
        'target':'_top'
//dynamically appending the input type file to the dynamically generated form and it MUST be appended to the page to work. "appendTo(body") submit then remove
 }).append($("#csvIdentifierFileBase")).appendTo('body').submit().remove();

});

现在名称是否重要

由于输入元素正在动态添加到表单中,因此名称必须与模型绑定器的控制器方法参数名称匹配才能生效。

[System.Web.Http.HttpPost]
public ActionResult Import(HttpPostedFileBase csvIdentifierFileBase)
{

}

基本上没有什么不同,然后在输入周围有一个表格标签,这是我试图避免的情况。我这样做的原因以及为什么我试图避免在页面上使用多个表单的原因是因为我遇到了嵌套表单标签无法正常工作的情况。