如何将图像文件和表单数据从 Ajax 传递到 MVC 控制器

Posted

技术标签:

【中文标题】如何将图像文件和表单数据从 Ajax 传递到 MVC 控制器【英文标题】:How to Pass Image File and Form Data From Ajax to MVC Controller 【发布时间】:2020-02-09 14:48:30 【问题描述】:

我有一个带有图像和另一个文件的表单,我想在控制器中发送带有图像的数据。

  <form id="first-form"  method="post" enctype="multipart/form-data">
   <div class="row">
      <div class="col-md-9">
       <div class="row">
        <div class="col-sm-6 form-group">
         @html.Label(@RegisterResource.Name, new  @class = "control-label" )
         <div class="field-input">
         @Html.TextBox("Name", null, new  placeholder = @RegisterResource.Name, autofocus = "autofocus", @class = "input-text" )
         @Html.ValidationMessage("Name", null, new  @class = "text-danger" )
        </div>
       </div>
      <div class="col-sm-6 form-group">
        @Html.Label(@RegisterResource.Family, new  @class = "control-label" )
         <div class="field-input">
         @Html.TextBox("Family", null, new  placeholder = @RegisterResource.Family, @class = "input-text" )
         @Html.ValidationMessage("Family", null, new  @class = "text-danger" )
        </div>
       </div>
       </div>
       <div class="row">
        <div class="col-sm-6 form-group">
          @Html.Label(@RegisterResource.CellPhone, new  @class = "control-label" )
           <div class="field-input">
           @Html.TextBox("CellPhone", null, new  placeholder = @RegisterResource.CellPhone, maxlength = 11, @class = "input-text", onkeydown = "return ValidateNumber(event);" )
            @Html.ValidationMessage("CellPhone", null, new  @class = "text-danger" )
           </div>
          </div>
          <div class="col-sm-6 form-group">
            @Html.Label(@ContractorResource.City, new  @class = "control-label" )
          <div class="field-input">
            @Html.DropDownList("CityId", (SelectList)ViewBag.City, new  placeholder = @ContractorResource.City, @class = "input-text" )
            @Html.ValidationMessage("CityId", null, new  @class = "text-danger" )
          </div>
         </div>
        </div>
        </div>
        <div class="col-md-3 text-center">
          <img id="image_upload_preview" class="img-circle" src="~/Content/Images/contractor-avator.png" />
          <br />
          <input type="file" id="inputFile" style="max-width: 200px" />
          <label for="inputFile" class="btn-2">انتخاب فایل تصویر</label>
         </div>
         </div>
         <div class="order-complate text-center">
         <button type="submit" class="awe-btn awe-btn-1 awe-btn-medium" id="user-register-btn" data-loading-text="<i class='fa fa-spinner fa-spin '></i> @PageResource.ConfirmCode">@PageResource.Continues</button>
         </div>
    </form>

在 jquery 中

function readURL(input) 
 if (input.files && input.files[0]) 
   var reader = new FileReader();
   reader.onload = function(e) 
     $('#image_upload_preview').attr('src', e.target.result);
 

 reader.readAsDataURL(input.files[0]);
 fileImage = input.files[0];
     


$("#inputFile").change(function() 
  readURL(this);
);

submitHandler: function() 
  $("#user-register-btn").button('loading');
  var data = $('#first-form').serialize();
  var formData = new FormData();  
  formdata.append("img", fileImage );             
  $.post("/Contractor/SendConfirmCode",
   data,
    function(result) 
      
    else 
     
   ,
  "json");

但在控制器中Request.FilesEmpty

【问题讨论】:

【参考方案1】:

感谢 @jishan 的全面解答;

如果我是你,我更喜欢使用视图模型来发布表单数据,但是,

根据您的看法:

    $('#user-register-btn').click(function (e) 

        e.preventDefault();

        $("#user-register-btn").button('loading');


        //var data = $('#first-form').serialize();
        var data = 
            Name: $('#Name').val(),
            Family: $('#Family').val(),
            CityId: $('#CityId').val(),
            CellPhone: $('#CellPhone').val()
        ;

        var formData = new FormData();

        formData.append("data", JSON.stringify(data));

        var totalFiles = document.getElementById('inputFile').files.length;
        for (var i = 0; i < totalFiles; i++) 
            var file = document.getElementById('inputFile').files[i];
            formData.append("httpPostedFileBase", file);
        
        $.ajax(
            type: "POST",
             url: '/Contractor/SendConfirmCode',
            data: formData,
            dataType: 'json',
            contentType: false,
            processData: false,
            success: function (response) 
                if (response != null) 
                    console.log(response);      
                  $('#image_upload_preview').attr('src', response[0].FilePath);                 
                
                else 
                    alert('No Response...!');
                
            ,
            error: function (error) 
                alert("error");
            
        );
        
    );

在您的控制器中

    [HttpPost]
    public ActionResult SendConfirmCode(HttpPostedFileBase[] httpPostedFileBase, string data)
    
        if(Request.Files.Count > 0)
        
            // as you wish
        


        ModelForm formData = JsonConvert.DeserializeObject<ModelForm>(data);
        // save formData to DB or ...

        return View();
    

以及与表单数据匹配的模型类

public class ModelForm

    public string Name  get; set; 
    public string Family  get; set; 
    public string CityId  get; set; 
    public string CellPhone  get; set; 

【讨论】:

【参考方案2】:

上传图片需要修改脚本。

在此示例中,当您使用文件控件“inputFile”选择文件时,会在视图中提及 jquery 文件更改事件。

查看单个文件的代码

 <div class="col-md-3 text-center">
      <img id="image_upload_preview" class="img-circle" src="~/Content/Images/contractor-avator.png" />
      <br />
      <input type="file" id="inputFile" style="max-width: 200px" />
      <label for="inputFile" class="btn-2">انتخاب فایل تصویر</label>
     </div>

查看代码选择多个文件

<div class="col-md-3 text-center">
          <img id="image_upload_preview" class="img-circle" src="~/Content/Images/contractor-avator.png" />
          <br />
          <input multiple="" type="file" id="inputFile" style="max-width: 200px" />
          <label for="inputFile" class="btn-2">انتخاب فایل تصویر</label>
         </div>

如果要选择多个文件或单个文件,此示例中的 Jquery 文件更改代码

/*FILE UPLOAD HERE*/
    var alldata = []
    $('#inputFile').change(function () 
        try 
            var formData = new FormData();
            var totalFiles = document.getElementById('inputFile').files.length;
            for (var i = 0; i < totalFiles; i++) 
                var file = document.getElementById('inputFile').files[i];
                formData.append("oHttpPostedFileBase", file);
            
            $.ajax(
                type: "POST",
                url: '/Contractor/SendConfirmCode',
                data: formData,
                dataType: 'json',
                contentType: false,
                processData: false,
                success: function (response) 
                    if (response != null) 
                        console.log(response);      
                      $('#image_upload_preview').attr('src', response[0].FilePath);                 
                    
                    else 
                        alert('No Response...!');
                    
                ,
                error: function (error) 
                    alert("error");
                
            );
         catch (e) 
            alert("File Upload Error" + e.message);
        
    );

用这个类在控制器文件中添加这段代码

#region FileUpload handling
        /*File Upload*/
        [HttpPost]
        public ActionResult BaseAutoFileUpload(HttpPostedFileBase[] oHttpPostedFileBase)
        
            try
                        
                List<FileUploadClass> lstUploadFile = new List<FileUploadClass>();          
                string yourfilepathfolder = "~/Uploads/Junk/";
                for (int i = 0; i < Request.Files.Count; i++)
                
                    FileUploadClass oFileUploadClass = new FileUploadClass();
                    var file = Request.Files[i];
                    var fileName = Path.GetFileName(file.FileName);
                    fileName = Guid.NewGuid().ToString() + "_" + fileName;
                    var path = Path.Combine(Server.MapPath(yourfilepathfolder), fileName);
                    file.SaveAs(path);
                    oFileUploadClass.FileName = fileName.Substring(37);
                    oFileUploadClass.FileNameForDelete = fileName;
                    oFileUploadClass.FilePath = path;
                    lstUploadFile.Add(oFileUploadClass);
                
                return Json(lstUploadFile);
            
            catch (Exception ex)
                           
                return Json(null);
            
        
        public class FileUploadClass
        
            public string FileName  get; set; 
            public string FilePath  get; set; 
            public string FileNameForDelete  get; set; 
        
        #endregion

注意:当您选择文件时,您的文件会自动保存在“yourfilepathfolder”中给定特定路径的服务器上。

如果你有单个文件选择并且你不会显示你选择了哪个文件

只需在代码中添加这一行

$('#image_upload_preview').attr('src', response[0].FilePath);

我已经为你添加了这一行,请检查。

签到控制台

【讨论】:

以上是关于如何将图像文件和表单数据从 Ajax 传递到 MVC 控制器的主要内容,如果未能解决你的问题,请参考以下文章

使用 jQuery 将表单数据作为数组传递给 Laravel

如何将值从表单传递到数据表

如何将文本字段数据从 Struts 2 中的 ajax 操作传递到原始调用 .jsp?

我如何将数据从控制器传递到组件 vue.js

如何在单个 Ajax 调用中发送表单字符串数据和图像数据

通过 Ajax 将裁剪的图像数据发送到 PHP