【问题标题】:Post image with Ajax and receive it in MVC action controller with Request.Files[""]使用 Ajax 发布图像并使用 Request.Files[""] 在 MVC 动作控制器中接收它
【发布时间】:2015-07-31 16:21:07
【问题描述】:

我有一个这样的 HTML Razor 视图:

@using (Html.BeginForm("Insert", "Operation", FormMethod.Post, new { @class = "form-horizontal", enctype = "multipart/form-data", id = "image_form" }))
{
   <div>
        <span class="btn btn-default ">
        <span class="fileinput-new">Up Your Image</span>
        <input type="file" name="nationalCard" id="nationalCard">
        </span>
  </div>
  <input type="button" class="btn btn-default" id="submit_image" onclick="insert()" value="ثبت" />
}

我的 Jquery Ajax 代码是:

 function insert() {
    var formData = $("#image_form");
    $.ajax({
        type: "POST",
        url: '@Url.Action("Insert", "Operation")',
        data: formData.serialize(),
        dataType: "json",
        success: function (data) {
            //do something...
        },
    });
};

所以我想基于 Request 对象和 Files 属性在动作控制器中接收图像,如下所示:

 [HttpPost]
 public ActionResult Insert()
 {
   if (Request.Files.Count > 0)
   {
      var image = Request.Files["nationalCard"];
      //do something...
   }
 }

我已经尝试过了,但实际上没有收到文件。知道谁能帮我做吗?

【问题讨论】:

  • 您已将multipart/form-data 添加到您的BeginForm,但您正在使用ajax 处理该帖子,因此您需要将enctype: 'multipart/form-data' 添加到您的ajax 调用中。查看这些答案以获得更多帮助stackoverflow.com/questions/2320069/… 我会查看一些更新的答案,而不仅仅是公认的答案
  • 谢谢,但我已经概述了链接并尝试了这个:'enctype: 'multipart/form-data' 但仍然无法正常工作。

标签: jquery ajax asp.net-mvc razor httprequest


【解决方案1】:

我看到的第一个问题是您的操作名称与您的 jQuery AJAX 调用中的操作不匹配。

 url: '@Url.Action("Insert", "Operation")',

需要改成

 url: '@Url.Action("InsertIdentification", "Operation")',

编辑

现在你的方法匹配了(至少在这里)我们可以试试这个。我在我的网站的 Javascript 文件中添加了这个。我找不到源,但我很确定我在 SO 上找到了它。通过 AJAX 上传文件显然存在困难,这个脚本通过修改 XHR 对象克服了这个问题。我将它与内置的 Ajax.BeginForm 一起使用,效果很好。

$(document).ready(function(){
 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)
                        {
                           //this is where you update your view or partial view
                            updateTarget.innerHTML = xhr.responseText;
                            $(":file").filestyle({ buttonBefore: true, buttonName: "btn btn-default", buttonText: "Browse" });
                        }
                    }
                }
            };
            xhr.send(new FormData(form));
        }
    }
}, true);

});

我还使用HttpPostedFileBase file 作为访问文件内容的操作的参数。

[HttpPost]
public ActionResult Insert(HttpPostedFileBase file)
{
   //do work with your file here...
}

【讨论】:

  • 您的表单是否已发布到操作中?你能用调试器检查一下吗?
  • 是的,我检查过了,表格已发送到行动。
  • 对于其他类型的数据,例如发送文本输入值,一切都很好,只是我无法通过 Request 对象和 Files 属性接收文件
【解决方案2】:

如果您已经解决了路由等问题...

您需要执行以下操作才能异步上传文件:

function uploadFileAjax(){
     var inputFileImage = document.getElementById("nationalCard"); // or $("#nationalCard")[0]
var file = inputFileImage.files[0];
var data = new FormData();
data.append('archivo',file);
$.ajax({
    url:"magicpath.php",
    type:"post",
    contentType:false,
    data:data,
    processData:false,
    cache:false,
    dataType:"json",
    success:function(data){
        console.log(data);
    },
    error:function(data){
        console.log(data);
    }
});
}

这应该成功地将文件上传到您的 php 脚本。取决于你的脚本如何移动它等等..

【讨论】:

    【解决方案3】:

    只需将 processDatacontentType 设置为 false 就可以了:

    function insert() {
        var reader = new FileReader();
    
        var selectedImage = document.getElementById('nationalCard').files[i];
    
        var formData = new FormData();
        formData.append('file', input.files[0]);
    
        $.ajax({
             url: '@Url.Action("Insert", "Operation")',
             data: formData ,
             type: 'POST',
             processData: false,
             contentType: false,
             success: function (result) { alert (result); }
       });
    };
    

    现在它将在您的操作方法中可用:

     [HttpPost]
     public ActionResult Insert()
     {
       if (Request.Files.Count > 0)
       {
          var image = Request.Files[0];
          //do something...
       }
     }
    

    这里的processDatajQuery 的含义如下:

    By default, data passed in to the data option as an object (technically,
    anything other than a string) will be processed and transformed into a query
    string, fitting to the default content-type "application/x-www-form-urlencoded". 
    If you want to send a DOMDocument, or other non-processed data, set this option to false.
    
    As of jQuery 1.6 you can pass false to **contentType** to tell jQuery to not set any content type header.
    

    【讨论】:

      猜你喜欢
      • 2020-12-24
      • 1970-01-01
      • 1970-01-01
      • 2023-03-13
      • 2016-12-21
      • 1970-01-01
      • 1970-01-01
      • 2012-09-08
      • 1970-01-01
      相关资源
      最近更新 更多