如何使用 AJAX JQuery ASP .NET MVC 4 将 FormCollection 和文件传递给控制器

Posted

技术标签:

【中文标题】如何使用 AJAX JQuery ASP .NET MVC 4 将 FormCollection 和文件传递给控制器【英文标题】:How to pass a FormCollection and file to controller with AJAX JQuery ASP .NET MVC 4 【发布时间】:2019-06-27 04:34:38 【问题描述】:

我有一个模型类:

public class Register

    public Employee Employee  get; set; 
    public Business Business  get; set; 

我有一个 html 表单,其输入类型文本包含来自 Model 的员工和业务数据以及一个用于加载图像的输入类型文件:

@using (Html.BeginForm(null, null, FormMethod.Post, new  @id = "frmRegister", @enctype = "multipart/form-data" ))

   @Html.AntiForgeryToken()
   <div class="div-file">
      <input id="inputFile" title="Upload a business image" type="file" name="UploadedFile" accept="image/*" />
   </div>
   <div class="div-input">
     @Html.Label("Name:", htmlAttributes: new  @for = "txtName" )
     @Html.EditorFor(model => model.Employee.Name, new  htmlAttributes = new  @class = "form-control", @id = "txtName"  )
   </div>
   <div class="div-input">
     @Html.Label("Age:", htmlAttributes: new  @for = "txtAge" )
     @Html.EditorFor(model => model.Employee.Age, new  htmlAttributes = new  @class = "form-control", @id = "txtAge"  )
   </div>
   <div class="div-input">
      @Html.Label("Company:", htmlAttributes: new  @for = "txtCompany" )
      @Html.EditorFor(model => model.Business.Name, new  htmlAttributes = new  @class = "form-control", @id = "txtName"  )
  </div>
  <div class="div-input">
       @Html.Label("Phone:", htmlAttributes: new  @for = "txtPhone" )
       @Html.EditorFor(model => model.Business.Phone, new  htmlAttributes = new  @class = "form-control", @id = "txtPhone"  )
  </div>
  <div class="text-center">
     <input type="button" id="btnRegister" value="Register" class="btn btn-default" />
   </div>

我使用 JQuery 从输入中获取信息并使用 AJAX 传递给控制器​​:

@section Scripts 
    <script type="text/javascript" language="javascript">
        $(document).ready(function () 
            $("#btnRegister").on('click', function (e) 
                e.preventDefault();
                var image = document.getElementById("inputFile").files[0];
                var frmRegister = $("#frmRegister").serialize();
                 $.ajax(
                    url: '@Url.Action("Create", "Register")',
                    type: 'POST',
                     traditional: true,
                     data: frmRegister,
                     dataType: 'json',
                     ContentType: "application/json;utf-8",
                     cache: false,
                     success: function (response) 

                     ,
                      error: function (response) 
                         alert(response.responseText);
                     
                );
            );
        );
    </script>

控制器:

public ActionResult Create(FormCollection collection)
      
            //HttpPostedFileBase file = Request.Files["UploadedFile"];
            return View();
      

问题是:图片文件也怎么传?

【问题讨论】:

This 可能会对您有所帮助。 不行,HttpPostedFileBase 文件 = Request.Files["UploadedFile"];为空。 【参考方案1】:

显然唯一的解决方案是将字符串编码转换的图像传递给base 64:

HTML:

@using (Html.BeginForm(null, null, FormMethod.Post, new  @id = "frmRegister", @enctype = "multipart/form-data" ))

   @Html.AntiForgeryToken()
   <div class="div-file">
      <input id="inputFile" title="Upload a business image" type="file" name="UploadedFile" accept="image/*" onchange="encodeImagetoBase64(this)"/>
   </div>
    <div>
        <p id="pImageBase64"></p>
    </div>
    <div>
        <img id="image" >
    </div>
   <div class="div-input">
     @Html.Label("Name:", htmlAttributes: new  @for = "txtName" )
     @Html.EditorFor(model => model.Employee.Name, new  htmlAttributes = new  @class = "form-control", @id = "txtName"  )
   </div>
   <div class="div-input">
     @Html.Label("Age:", htmlAttributes: new  @for = "txtAge" )
     @Html.EditorFor(model => model.Employee.Age, new  htmlAttributes = new  @class = "form-control", @id = "txtAge"  )
   </div>
   <div class="div-input">
      @Html.Label("Company:", htmlAttributes: new  @for = "txtCompany" )
      @Html.EditorFor(model => model.Business.Name, new  htmlAttributes = new  @class = "form-control", @id = "txtName"  )
  </div>
  <div class="div-input">
       @Html.Label("Phone:", htmlAttributes: new  @for = "txtPhone" )
       @Html.EditorFor(model => model.Business.Phone, new  htmlAttributes = new  @class = "form-control", @id = "txtPhone"  )
  </div>
  <div class="text-center">
     <input type="button" id="btnRegister" value="Register" class="btn btn-default" />
   </div>

脚本:

@section Scripts 
    <script type="text/javascript" language="javascript">
        $(document).ready(function () 
            $("#btnRegister").on('click', function (e) 
                e.preventDefault();
                var imagenBase64 = $("#pImageBase64").html();
                var name = $("#txtName").val();
                var age= $("#txtAge").val();
                var params = 
                    file: imagenBase64,
                    name: name,
                    age: age
                
                 $.ajax(
                    url: '@Url.Action("Create", "Register")',
                    type: 'POST',
                     traditional: true,
                     data: params,
                     dataType: 'json',
                     ContentType: "application/json;utf-8",
                     cache: false,
                     success: function (response) 

                     ,
                      error: function (response) 
                         alert(response.responseText);
                     
                );
            );
        );
        function encodeImagetoBase64(element) 
            var file = element.files[0];
            var reader = new FileReader();
            reader.onloadend = function () 
                $("#image").attr("src", reader.result);
                $("#pImageBase64").html(reader.result);

            
            reader.readAsDataURL(file);
        
    </script>

控制器:

public ActionResult Create(string file, string name, string age)

  return Json("success!!!");

【讨论】:

【参考方案2】:

请这样做,尝试使用FormCollection:

@section Scripts 
    <script type="text/javascript" language="javascript">
        $(document).ready(function () 
            $("#btnRegister").on('click', function (e) 
                e.preventDefault();
                var image = document.getElementById("inputFile").files[0];
                var frmRegister = $("#frmRegister").serialize();

                var formData = new FormData();
                formData.append("imageFile", image );
                formData.append("RegisterData", frmRegister);
                 $.ajax(
                    url: '@Url.Action("Create", "Register")',
                    type: 'POST',
                     traditional: true,
                     data: formData,
                     processData: false,
                     dataType: 'json',
                     ContentType: false,
                     cache: false,
                     success: function (response) 

                     ,
                      error: function (response) 
                         alert(response.responseText);
                     
                );
            );
        );
    </script>

并根据这个改变Action方法:

[HttpPost]
        public ActionResult Create()
        
            string serializedRegisterData = Request["RegisterData"]; //you can do code of deserialization for form data.

            var image= Request.Files[0];
            var imagePath = Path.GetFileName(image.FileName);

            return Json("");
        

【讨论】:

浏览器抛出此消息:TypeError: 'append' called on an object that does not implement interface FormData. 让我检查一下。 language="javascript" 请从脚本标签中删除它。谢谢。 请同时添加 --> processData: false,在 ajax 调用参数中。原因:默认情况下,作为对象(从技术上讲,除了字符串之外的任何内容)传入 data 选项的数据将被处理并转换为查询字符串,适合默认的内容类型“application/x-www-form- urlencoded”。如果要发送 DOMDocument 或其他未处理的数据,请将此选项设置为 false。 谢谢,我删除了 language="javascript" 并在 ajax 调用参数中添加了 processData: false,但在控制器 Request["RegisterData"];为 null 且 Request.Files 为空。

以上是关于如何使用 AJAX JQuery ASP .NET MVC 4 将 FormCollection 和文件传递给控制器的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET 2.0 JQuery AJAX 登录

如何使用 jQuery Ajax 调用从 ASP.NET Web Api 下载 CSV 文件

如何在带有 ADO.NET 的 ASP.NET Core MVC 中使用 jQuery Ajax 自动完成

如何在 c# ASP.Net 中使用有效的 JSON 输出创建 JSON WebService 并使用 JQuery/Ajax 进行查询

如何使用 jquery ajax 在 asp.net 中提交值数据表

如何使用 ASP.NET MVC Rest API 调用和 jQuery Ajax 下载文件