Ajax.BeginForm 未按预期工作

Ajax.BeginForm is not working as expected

Aajx.BeginForm 我有一个非常奇怪的问题。我有这个代码:

在视图中:

@using (Ajax.BeginForm("Upload", "Profile", new AjaxOptions() { HttpMethod = "POST" }, new { enctype = "multipart/form-data" }))
    {
        @Html.AntiForgeryToken()
        <input type="file" name="files"><br>
        <input type="submit" value="Upload File to Server">
    }

在控制器中:

[HttpPost]
[ValidateAntiForgeryToken]
public void Upload(IEnumerable<HttpPostedFileBase> files)
{
    if (files != null)
    {
        foreach (var file in files)
        {
            // Verify that the user selected a file
            if (file != null && file.ContentLength > 0)
            {
                // extract only the fielname
                var fileName = Path.GetFileName(file.FileName);
                // TODO: need to define destination
                var path = Path.Combine(Server.MapPath("~/Upload"), fileName);
                file.SaveAs(path);
            }
        }
    }
}

问题是我在提交表单时得到空文件。我读了很多与我的问题相同的问题,但大多数答案是输入类型="file" 的名称与控制器中的参数名称不同。我找到了一些例子,我尝试 this one 除了 jquery 文件外,这与我的代码几乎相同,所以我尝试用这些文件替换 jquery 文件:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.js"></script>
<script src="http://malsup.github.com/jquery.form.js"></script>

惊喜来了!!提交表格后,我得到了文件,但表格 post 回来了。因为没有ajax所以是工作。我在 google 中搜索 Ajax.BeginFrom 即 post 并在 Whosebug 中找到许多解决方案,大多数答案是 jquery.unobtrusive-ajax 文件必须包含在页面中。它就像一个问题的循环,一旦你解决了一个问题,你就会遇到另一个问题。我错过了什么吗?

您需要在表单中指定编码类型。

   @using (Ajax.BeginForm("Upload", "ControllerName", new AjaxOptions { HttpMethod = "POST"}, new { enctype = "multipart/form-data"}))
    {
        @Html.AntiForgeryToken()
        <input type="file" name="files"><br>
        <input type="submit" value="Upload File to Server">
    }

您不能使用 Ajax.BeginForm() 提交文件。助手使用 jquery.unobtrusive-ajax.js 文件使用不允许 multipart/form-data enctype.

的 ajax 函数提交数据

一种选择是使用 FormData(但在旧版浏览器中不受支持)。将 Ajax.BeginForm() 更改为 Html.BeginForm() 然后处理表单提交事件

$('form').submit(function() {
  var formdata = new FormData($('form').get(0));
  $.ajax({
    url: '@Url.Action("YourActionName", "YourControllerName")',
    type: 'POST',
    data: formdata,
    processData: false,
    contentType: false,
    success: function() {
      .... // do something?
    }       
  });
});

此外,还有许多 jquery 插件可用于上传文件(列出了其中的 14 个 here

旁注:您的文件输入只允许选择一个文件,因此您的方法参数应为 HttpPostedFileBase files(而不是 IEnumerable<HttpPostedFileBase> files),或者在文件输入。