Search code examples
javascriptasp.net-mvc-5

Pass data to same Controller from 2 different jquerys in asp.net mvc


My project consists on making an OCR read on an image from coordinates drawn by the user.So i have made 2 external javascripts one manipulates the rectangles and the second manipulates the file(delete, preview..)

FileUpload.JS

function saveImage() {
var file = $("#imageBrowser").get(0).files;
var data = new FormData;
data.append("ImageFile", file[0]);
$.ajax({
    async: true,
    type: "POST",
    dataType: "JSON",
    url: "/OcrImage/OcrOnImage",
    data: data,
    processData: false,
    contentType: false,
    
  })
 }

RectangleDrawing.js

$(function () {
$('#btnSend').click(function (e) {
    $.ajax({
        type: "POST",
        contentType: "application/json;charset=utf-8",
        data: JSON.stringify(boundingBoxes),
        url: "/OcrImage/OcrOnImage",
    });
    });
});

the Controller

 [HttpPost]
    public ActionResult OcrOnImage(ImageUploadModel objeImageViewModel, Coordinate[] Coordinates)
    {//code}

My question is how can i pass data from each javascripts to a single controller through a single submit.Keep in mind that i have tried to upload the file using razorview and i could pass only one data which is either Coordinates or the file to upload.

If there's a better method to do this please let know with an example.Thank you in advance. I can provide more info if not clear.


Solution

  • If you want to file upload with view models (in your case ImageUploadModel) then you need to consider two things.

    1. Your view model should contains a property of type HttpPostedFileBase like below:

      HttpPostedFileBase ImageUpload { get; set; }

    2. You should have strongly typed view with model bindings. something like below:

    @model ImageUploadModel
        <form action="" method="post" enctype="multipart/form-data">
        <div>
            @Html.LabelFor(m => m.ImageUpload)
            @Html.EditorFor(m => m.ImageUpload)
        </div>
        <button type="submit">Create</button>
    

    You could use @using (Html.BeginForm()) { ... } helper alternative to using form if you want to but for fileupload you must have this enctype="multipart/form-data" attribute.

    Controller code would be like below:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult OcrOnImage(ImageUploadModel model)
    {
        var validImageTypes = new string[]
        {
            "image/gif",
            "image/jpeg",
            "image/pjpeg",
            "image/png"
        }
    
        if (model.ImageUpload == null || model.ImageUpload.ContentLength == 0)
        {
            ModelState.AddModelError("ImageUpload", "This field is required");
        }
        else if (!imageTypes.Contains(model.ImageUpload.ContentType))
        {
            ModelState.AddModelError("ImageUpload", "Please choose either a GIF, JPG or PNG image.");
        }
    
        if (ModelState.IsValid)
        {
            var image = new Image
            {
                Title = model.Title,
                AltText = model.AltText,
                Caption = model.Caption
            }
    
            if (model.ImageUpload != null && model.ImageUpload.ContentLength > 0)
            {
                var uploadDir = "~/uploads"
                var imagePath = Path.Combine(Server.MapPath(uploadDir), model.ImageUpload.FileName);
                var imageUrl = Path.Combine(uploadDir, model.ImageUpload.FileName);
                model.ImageUpload.SaveAs(imagePath);
                image.ImageUrl = imageUrl;
            }
    
            db.Create(image);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
    
        return View(model);
    }
    

    I have never faced like this situation where file upload and another action is going with along , it is some violation of SRP (single responsibility principle). By the way you can try coordination with js as you described above on putting Coordinate list/array in controller action like below and let me is that works or not.

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult OcrOnImage(ImageUploadModel model,Coordinate[] Coordinates) {//like above}