2
\$\begingroup\$

I am currently developing an e-commerce website where users can upload their photos to customise their products. The use case begins when the user selects a product from our website (e.g. shirt). After that, they will select the quantity and upload their photos. The client-side will then append the following fields to the using FormData: productId, productName and imageBlob. The imageBlob is the user uploaded images. I will then send these data over to my server-side (asp.net core) for sanitisation by checking the productId received with the database. I feel that there is a lot of improvement that can be done to my code but I just do not have the knowledge to do so. Is there anyone that can give feedback or help to improve my code?

Client-side (JavaScript)

function b64toBlob(b64Data, contentType, sliceSize) {
    contentType = contentType || "";
    sliceSize = sliceSize || 512;

    var byteCharacters = atob(b64Data);
    var byteArrays = [];

    for (
      var offset = 0;
      offset < byteCharacters.length;
      offset += sliceSize
    ) {
      var slice = byteCharacters.slice(offset, offset + sliceSize);

      var byteNumbers = new Array(slice.length);
      for (var i = 0; i < slice.length; i++) {
        byteNumbers[i] = slice.charCodeAt(i);
      }

      var byteArray = new Uint8Array(byteNumbers);

      byteArrays.push(byteArray);
    }

    var blob = new Blob(byteArrays, { type: contentType });
    return blob;
  }

  function imagetoblob(base64Image) {
    // Split the base64 string in data and contentType
    var block = base64Image.split(";");
    // Get the content type of the image
    var contentType = block[0].split(":")[1]; // In this case "image/gif"
    // get the real base64 content of the file
    var realData = block[1].split(",")[1]; // In this case "R0lGODlhPQBEAPeoAJosM...."

    // Convert it to a blob to upload
    return b64toBlob(realData, contentType);
  }

  const formData = new FormData();

  for (var i = 0; i < userProducts.length; i++) {
    formData.append("arr[" + i + "]", userProducts[i].productId);
    formData.append("arr[" + i + "]", userProducts[i].productName);
    formData.append(
      "arr[" + i + "]",
      imagetoblob(userProducts[i].base64Image)
    );
  }

Server-side (ASP.NET Ccore)

[AllowAnonymous]
[HttpPost("sanitizeUserCart")]
public async Task<IActionResult> sanitizeUserCart([FromForm] IFormCollection inFormData)
{

    List<Task<Product>> productTasks = new List<Task<Product>>();

    try
    {
        foreach (var key in inFormData.Keys)
        {
            if (key.Contains("arr"))
            {
                int i = 0;
                var id = int.Parse(inFormData[key][0]);
                var name = inFormData[key][1];
                var image = inFormData.Files[i];
                productTasks.Add(_productService.GetUserCart(id, name));
                i++;
            }

        }
        var productResults = await Task.WhenAll<Product>(productTasks);
        return new JsonResult(productResults);
    }
    catch (Exception ex)
    {
        // return error message 
        return BadRequest(new { message = ex.Message });
    }
}
\$\endgroup\$
6
  • \$\begingroup\$ I would suggest adopting a more strongly typed approach. You can use the code from this question as an inspiration. For now, your product server-side handling looks shady on too many levels. \$\endgroup\$ Commented Jun 10, 2019 at 10:04
  • \$\begingroup\$ Hi @BohdanStupak May I know why is it "shady on too many levels"? What needs to be changed? \$\endgroup\$ Commented Jun 10, 2019 at 11:44
  • \$\begingroup\$ arr is some sort of magic string. you have to keep in mind that it should be synced on a client and on a backend. Your parsing logic is hard to comprehend. Looks rely on the fact that your files are sent in some sort of exact order, and it takes quite a lot of time to figure that out. Also, you actually never use the image var so I doubt if there any need to parse it. \$\endgroup\$ Commented Jun 10, 2019 at 12:17
  • \$\begingroup\$ @BohdanStupak Thanks for the reply! As for your comment, "Looks rely on the fact that your files are sent in some sort of exact order". I am trying to avoid that but I do not know, the only way that I could think of is in exact order. Is there a better way to retrieve the data without following an order? \$\endgroup\$ Commented Jun 10, 2019 at 12:23
  • \$\begingroup\$ I do think that the best idea is to leave mapping to ASP.NET core as per my first comment \$\endgroup\$ Commented Jun 10, 2019 at 13:16

0

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.