Why do I have to use FormData to send files via Ajax?

2

I created an HTML page with a form, and in it a imput file and a hidden field, all of them with the name attribute.

<form id="meuForm" action="..." method="POST">
  <input type="hidden" name="itemId" value="1" />
  <input type="file" name="arquivo" accept=".csv" required />
  <input type="submit" value="Enviar" />
</form>

When trying to receive values as parameters in my Action I did not succeed with the file, only with the other hidden field. I then tried to get the file through Request , but again I did not succeed.

[HttpPost]
public ActionResult Upload(int itemId, HttpPostedFileBase arquivo)
{
   // Forma alternativa
   var arquivoTeste = Request.Files["arquivo"];
}

To send the form I then tried to use Ajax.BeginForm , but after several attempts I gave up.

@using (Ajax.BeginForm("Upload", "MeuController", new AjaxOptions()
{
    HttpMethod = "POST",
    OnSuccess = "ExibeRetorno",
    OnBegin = "IniciaLoad",
    OnFailure = "alert('Deu pau!')",
    OnComplete = "FinalizaLoad();"
}))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

  <input type="hidden" name="itemId" value="1" />
  <input type="file" name="arquivo" accept=".csv" required />
  <input type="submit" value="Enviar" />

}

I built all ajax via JavaScript, but nothing worked.

<form id="meuForm">
  <input type="hidden" name="itemId" id="itemId" value="1" />
  <input type="file" name="arquivo" id="arquivo" accept=".csv" required />
  <input type="button" id="enviar" value="Enviar" />
</form>

<script>
   (function(){
       $("#enviar").click(function(){
           var _itemId = $("#itemId).val();
           var _arquivo = $("#arquivo").get(0).files[0];

           $.ajax({
              beforeSend: function () {
                  IniciaLoad();
              },
              complete: function () {
                  FinalizaLoad();
              },
              contentType: "application/json, charset=utf-8",
              dataType: "json",
              type: "POST",
              url: '@Url.Action("Upload", "MeuController"})',
              data: JSON.stringify({
                    itemId: _itemId,
                    arquivo: _arquivo
              }),
              success: function (data) {

              },
              fail: function () {

               },
               error: function () {

               }
          });


       });

   })();
</script>

After several searches I have found instead to use the FormData , and I was successful !

In my ajax (last given example), I made the following changes:

var formData = new FormData();
formData.append("arquivo", _arquivo);
formData.append("itemId", _itemId);


$.ajax({
       ...
       contentType: false,
       processData: false,
       data: formData,
       ...
});

But I did not find a detailed answer as to why I could not send the file by the above methods, but only with FormData .

  

1 - Why did not the above methods work?

     

2 - What's different about FormData that makes it work?

    
asked by anonymous 06.09.2016 / 22:08

1 answer

2

I ended up searching more and found the reason.

There is an attribute in the form called enctype , it is defined as the form data must be encoded when sending it to the server.

By default enctype="application/x-www-form-urlencoded" if nothing is specified, and in this case it is not possible to send files to the server.

To solve this, simply specify the value of the attribute as multipart/form-data , because in this encoding format you can send files to the server. And then you do not need ajax, but just do everything normally with the submit form.

But if sending is done directly in javascript with ajax (it defaults to the same type of encoding), then just use the FormData interface referenced in the question.

Font1

    
06.09.2016 / 22:25