Uploading an image to a file using javascript and entity framework

You can use javascript to resize a photo before posting to entity framework. The following html is included in a form with the id “formdata” and adds bootstrap for formatting.

Form Html

  <div class="form-group">
                <label asp-for="Photo" class="control-label"></label>
                <label class="control-label">Upload a photo</label>
                <div class="col-md-10">
                    <input type="file" name="Upload" id="Upload" onchange="loadImageFile();">
                </div>
                 <div>
                    <img id="my_photo" src="@src">
                </div>
</div>

Next step, resize the photo

The image is checked that is exists and that it has a valid image type. Then the image is resized to a max of 500 pixels height or width and uploaded with ajax. No submit button is required.

Javascript to resize and upload

var loadImageFile = function () {

    var uploadImage = document.getElementById("Upload");
    //check and retuns the length of uploded file.
    if (uploadImage.files.length === 0) {
        return;
    }

    //Is Used for validate a valid file.
    var uploadFile = document.getElementById("Upload").files[0];
    var filterType = /^(?:image\/bmp|image\/cis\-cod|image\/gif|image\/ief|image\/jpeg|image\/jpeg|image\/jpeg|image\/pipeg|image\/png|image\/svg\+xml|image\/tiff|image\/x\-cmu\-raster|image\/x\-cmx|image\/x\-icon|image\/x\-portable\-anymap|image\/x\-portable\-bitmap|image\/x\-portable\-graymap|image\/x\-portable\-pixmap|image\/x\-rgb|image\/x\-xbitmap|image\/x\-xpixmap|image\/x\-xwindowdump)$/i;

    if (!filterType.test(uploadFile.type)) {
        alert("Please select a valid image.");
        return;
    }

    fileReader.readAsDataURL(uploadFile);
}
var fileReader = new FileReader();

fileReader.onload = function (event) {
   
    var image = new Image();
    image.src = event.target.result;
    var theurl="example.com";
    image.onload = function () {
        var uploadImage = document.getElementById("Upload").files[0];
            data = resize(image);
            var formdata_el = document.getElementById("formdata");
            formdata = new FormData(formdata_el);
            formdata.set('base64String', data);
            $.ajax({
                url: theurl,
                method: "Post",
                data: formdata,              
                contentType: false,
                cache: false,
                processData: false,
                success: function (result) {
                    document.getElementById("my_photo").src = data;
                },
                error: function () {
                    alert("error");
                }
            }); // end of ajax
    }
};
function resize(image) {
    //returns image of max width or height of 500px
    var canvas = document.createElement("canvas");
    var context = canvas.getContext("2d");    
   
    var maxWidth = 500;
    var maxHeight = 500;
    var width = image.width;
    var height = image.height;
    if (width &gt; height) {
        if (width &gt; maxWidth) {
            height *= maxWidth / width;
            width = maxWidth;
        }
    } else {
        if (height &gt; maxHeight) {
            width *= maxHeight / height;
            height = maxHeight;
        }
    }
    canvas.width = width;
    canvas.height = height;
   
    context.drawImage(image,
        0,
        0,
        image.width,
        image.height,
        0,
        0,
        canvas.width,
        canvas.height
    );
 
   
    return canvas.toDataURL()
}

The ajaxed photo is processed by the server.

This last part show the Post in the C# back end. The Model is Tour. The Tour ID is the userid from the Identity Database. The folder for upload to is specified. The Upload field is used to get the file name, but not used to receive the file. The upload file has been converted by javascript to base64 and added to the posted form data. The server now reads that base64 string, converts it into a byte array and reads it into a memory stream. The memory stream is used by the filestream class to upload the file. Finally, any other files for this TourID are removed.

C# backend to upload the file


[BindProperty]
        public Microsoft.AspNetCore.Http.IFormFile Upload { get; set; }
 [BindProperty]
        public String base64String { get; set; }

      public async Task<IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return Page();
            }

            _context.Attach(Tour).State = EntityState.Modified;
            var user = await _userManager.FindByEmailAsync(User.Identity.Name);
            Tour.UserID = user.Id;

            // upload the photo file

            string fileName;            
            string path = Path.Combine(_environment.WebRootPath, "Tours", "Photos", "Tours");
            //check if file was uploaded.
            if (Upload != null) {
                // the client has resized the file and sent a base64 string
                //remove front text
                base64String = base64String.Replace("data:image/png;base64,", String.Empty);
                // convert from base64 to a byte array
                byte[] imageBytes = Convert.FromBase64String(base64String);
                //read into memory stream
                MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);

                fileName = "Tour" + Tour.ID  + "_" + Path.GetFileName(Upload.FileName);
                using (FileStream stream = new FileStream(Path.Combine(path, fileName), FileMode.Create))
                {
                    // copy the memory stream to the filestream
                    ms.CopyTo(stream);
                    Tour.Photo = fileName;
                }
                ms.Close();
               
            }
          
            try
            {
               
                // remove any  photo files not matching current file
                String sourceDirectory = Path.Combine(_environment.WebRootPath, "Tours", "Photos", "Tours");

                var files = Directory.EnumerateFiles(sourceDirectory, "*Tour" + Tour.ID + "_*");
                foreach (string currentFile in files)
                {
                    if (currentFile != Path.Combine(_environment.WebRootPath, "Tours", "Photos", "Tours") + @"\"  + Tour.Photo)
                    {
                        System.IO.File.Delete(currentFile);
                    }
                }
             
                await _context.SaveChangesAsync();

            }
            catch (DbUpdateConcurrencyException)
            {
                if (!TourExists(Tour.ID))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            return Page();
        }

Leave a Reply

Your email address will not be published. Required fields are marked *