无法通过AJAX将表单数据和文件上传发送到控制器

时间:2022-02-20 18:13:44

I am trying to send a bunch of form data from my view and map it to a ViewModel parameter in my controller. In addition, I am trying to send a file with this request which will map to a separate parameter.

我试图从我的视图发送一堆表单数据并将其映射到我的控制器中的ViewModel参数。另外,我试图发送一个带有此请求的文件,该文件将映射到一个单独的参数。

When formData is sent through to the controller, it correctly maps the file upload to the file parameter, however, the model parameter properties are all null/defaults.

当formData发送到控制器时,它会正确地将文件上载映射到file参数,但是,模型参数属性都是null / defaults。

In summary, my question is this: how do I map my form element values to to MyViewModel paramter in my controller whilst sending a file too?

总之,我的问题是:如何在发送文件的同时将我的表单元素值映射到我的控制器中的MyViewModel参数?

Model:

public class MyViewModel
{
    public int AsssumptionSetId { get; set; }
    public int BuildingBlockId { get; set; }
    public string ReplacementCode { get; set; }
    public decimal Rounding { get; set; }
    public string DataSource { get; set; }
    public bool AER { get; set; }
    public int Term { get; set; }
}

View:

This view is strongly typed to the MyViewModel:

此视图是MyViewModel的强类型:

<form id="buildingBlockForm">

    @Html.HiddenFor(model => model.AsssumptionSetId)
    @Html.HiddenFor(model => model.BuildingBlockId)

    @Html.TextBoxFor(m => m.ReplacementCode)

    @Html.TextBoxFor(m => m.Rounding)

    @Html.DropDownListFor(m => m.DataSource, (SelectList)ViewBag.DataSources)

    @Html.DropDownListFor(m => m.Term, (SelectList)ViewBag.Terms)

    @Html.CheckBoxFor(m => m.AER)

    <input type="file" id="file" name="file" />

    <input class="button green-button" type="submit" value="Create" />

</form>

Controller:

  public ActionResult CreateBuildingBlock(MyViewModel model, HttpPostedFileBase file)
        {
            // all of the 'model' properties = null instead of the form values
            // file = the file I chose to upload and works as expected
        }

JS:

var formData = new FormData($('#buildingBlockForm'));

// Get file and append to form data (Should only be 1)
$.each(Files["csv"], function (key, value) {
    formData .append("file", value);
});

// Send file
$.ajax({
    url: '/Assumptions/CreateBuildingBlock',
    type: 'POST',
    data: formData,
    cache: false,
    dataType: "json",
    contentType: false,
    processData: false,

    success: function (response) {
        // Handle success
    },
    error: function (xhr, status, errorThrown) {
        // Handle errors
    }
});

2 个解决方案

#1


Turns out I was missing an index when grabbing the form that needs serializing.

当抓住需要序列化的表单时,我错过了一个索引。

new FormData($('#buildingBlockForm')[0]);

This solved my issue.

这解决了我的问题。

#2


since your form contains a file-input type, you need your form to handle this submission (enctype).

由于您的表单包含文件输入类型,您需要表单来处理此提交(enctype)。

<form id="buildingBlockForm" enctype="multipart/form-data"> 

Also, if you want to stick with MVC's form helper, it would alleviate the issues you may have with a script-based ajax post.

此外,如果你想坚持使用MVC的表单助手,它可以缓解你在基于脚本的ajax帖子中可能遇到的问题。

@using (Ajax.BeginForm("CreateBuildingBlock", "Assumptions", null, new AjaxOptions { HttpMethod = "POST", OnSuccess = "postSuccess", OnFailure = "postFailed" }, new { enctype = "multipart/form-data" }))
{
  // your form fields here
}

<script>
  function postSuccess() {
    // handle success here
  }

  function postfailed() {
    // handle failed post here
  }
</script>

#1


Turns out I was missing an index when grabbing the form that needs serializing.

当抓住需要序列化的表单时,我错过了一个索引。

new FormData($('#buildingBlockForm')[0]);

This solved my issue.

这解决了我的问题。

#2


since your form contains a file-input type, you need your form to handle this submission (enctype).

由于您的表单包含文件输入类型,您需要表单来处理此提交(enctype)。

<form id="buildingBlockForm" enctype="multipart/form-data"> 

Also, if you want to stick with MVC's form helper, it would alleviate the issues you may have with a script-based ajax post.

此外,如果你想坚持使用MVC的表单助手,它可以缓解你在基于脚本的ajax帖子中可能遇到的问题。

@using (Ajax.BeginForm("CreateBuildingBlock", "Assumptions", null, new AjaxOptions { HttpMethod = "POST", OnSuccess = "postSuccess", OnFailure = "postFailed" }, new { enctype = "multipart/form-data" }))
{
  // your form fields here
}

<script>
  function postSuccess() {
    // handle success here
  }

  function postfailed() {
    // handle failed post here
  }
</script>