Sending byte array over ajax

Asked by At

I am having ajax request which is working only half way.

function receivedText() {
    alert(fr.result); //Here i have good result
    $.ajax({
        type: "POST",
        url: "/Gallery/UploadImage",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        data: {
            byteArray: fr.result,
            fileName: $('input[type=file]').val().split('\\').pop()
        },
        success: function (data) {
            if (data == 0)
                alert("error");
            else
                alert("Success");
        },
        error: function () {
            alert("ERROR");
        }
    });
}

Here is my request. As you can see i commented up there that in my test(alert) fr.result has value BUT when i debug and go see it in my controller, it is NULL.

Here is my controller.

[HttpPost]
public IActionResult UploadImage(byte[] byteArray, string fileName)
{
    try
    {
        System.IO.File.WriteAllBytes(_hostingEnvironment.WebRootPath + "\\Uploads\\Images\\" + fileName, byteArray);
        return Json(0);
    }
    catch
    {
        return Json(0);
    }
}

2 Answers

1
itminus On

Your're using ajax in a wrong way.

  1. The first error is a mismatch with Content-Type

    $.ajax({
        ...
        contentType: "application/json; charset=utf-8",
        ...
        data: {
            byteArray: fr.result,
            fileName: $('input[type=file]').val().split('\\').pop()
        },
        ...
    } 
    

    Although you've set the Content-Type=application/json, the payload sent to server will be form-url-encoded by default:

    fileName=Xyz&byteArray=
    

    If you need JSON format, you should use JSON.stringify({...}) to get a text representation.

  2. The contentType: "application/json; is not suitable here. That's because :

    • The JSON is not designed to deal with binary data but used for text. You can't send a byte[] with json.
    • The server side code expects simple type from query/routes/form. If you need json, they should be something like IActionResult UploadImage([FromBody] Fr fr)
  3. If you're sending an image, the easiest way is to use the Content-Type of multipart/form-data with the IFormFile on the server side at the same time.

    // action method
    public IActionResult UploadImage(IFormFile image, string fileName)
    {
         // ...
    }
    

    and now you could send a FormData :

    // your receivedText() function
    function receivedText(){
        var formData = new FormData();
        formData.append('fileName', 'Xyz.img');
    
        // if you need upload image
        var inputFileElement=document.getElementById("inputFileImage");
        formData.append('image', inputFileElement.files[0]);
    
        // of if you're already have a `byte[]`, you could do it as below:
        // var blob = new Blob([bytearray]...); // see https://developer.mozilla.org/en-US/docs/Web/API/Blob/Blob
        // formData.append('image', blob); 
    
        $.ajax({
            type: "POST",
            url: "/Gallery/UploadImage",
            contentType: false,
            processData: false,
            data: formData,
            success: function (data) {
                console.log(data);
                // ...
            },
            error: function () {
                // ...
            }
        });
    }
    
1
Romain On

That would be your idea:

public class UploadImageBindings {
   public string byteArray {get;set;}
   public string fileName {get;set;}
}

[HttpPost]
public IActionResult UploadImage(UploadImageBindings bindings)
{
    try
    {
     var bytes = System.Text.Encoding.UTF8.GetBytes(bindings.byteArray);
        System.IO.File.WriteAllBytes(_hostingEnvironment.WebRootPath + "\\Uploads\\Images\\" + bindings.fileName, bytes);
        return Json(0);
    }
    catch
    {
        return Json(0);
    }
}

Your problem is that you not post as byte[] but you have to post as string !