0

I have a model class:

public class Register
{
    public Employee Employee { get; set; }
    public Business Business { get; set; }
}

I have a HTML form with inputs type text with Employee and Business data from Model and a input type file to load an image:

@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>
}

I take the information from inputs with JQuery and pass to Controller with 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>
}

The controller:

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

The question is: How to pass the image file too?

marc_s
  • 675,133
  • 158
  • 1,253
  • 1,388
Ejrr1085
  • 561
  • 1
  • 6
  • 17

2 Answers2

1

Apparently the only solution is to pass the image converted in string encode to 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" height="150">
    </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>
}

SCRIPT:

@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>
}

The controller:

public ActionResult Create(string file, string name, string age)
{
  return Json("success!!!");
}
marc_s
  • 675,133
  • 158
  • 1,253
  • 1,388
Ejrr1085
  • 561
  • 1
  • 6
  • 17
0

Please do this way, try to use 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>
}

And Change Action method according to this:

[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("");
        }
Ali Hassan
  • 79
  • 2
  • 14
  • The browser throw this message: TypeError: 'append' called on an object that does not implement interface FormData. – Ejrr1085 Feb 03 '19 at 16:16
  • Let me check this. – Ali Hassan Feb 03 '19 at 18:08
  • language="javascript" PLease remove this from the script tag. Thank you. – Ali Hassan Feb 03 '19 at 18:17
  • Please also add this --> processData: false, in ajax call parameter. REASON: By default, data passed in to the data option as an object (technically, anything other than a string) will be processed and transformed into a query string, fitting to the default content-type "application/x-www-form-urlencoded". If you want to send a DOMDocument, or other non-processed data, set this option to false. – Ali Hassan Feb 03 '19 at 18:22
  • Thanks, I removed language="javascript" and I added processData: false in ajax call parameter, but in the controller Request["RegisterData"]; is null and Request.Files is empty. – Ejrr1085 Feb 03 '19 at 20:55
  • contentType: false, It will work now. You may have a look. Thank you. – Ali Hassan Feb 04 '19 at 07:20