1

Been scratching my head a lot for the past two week about trying to figure this out.

Summernote (https://github.com/HackerWins/summernote) is my preferred editor, but I need the images to be uploaded to S3 instead of being saved as base64, as this will be too large for the database, etc. On the summernote github page I have found this (https://github.com/HackerWins/summernote/issues/72), but there is not a .net code sample.

I am fine with uploading files to S3 from my asp website, my problem is that how should I 'send' the file to my webmethod, yes I am using a webmethod as the summernote code is handled in js, in a way that asp would understand it?

I have tried sending the 'file', and receiving it as an object on my server side, but this only results in a "[object File]" string being received.

I am coding in VB, but C# code will also be appreciated!

Thanks in advance.

user3714778
  • 11
  • 1
  • 3

2 Answers2

3

I don't know any VB so I hope this C# code will help you.

First of all I've never used amazon-s3 therefor I won't provide an example to it's specifics however whilst making a quick search I've found another thread where a user points out on how to actually upload a image to amazon using a memory stream here.

An option would be to create a upload action server side, here's a snippet in C# using MVC:

    [HttpPost]
    public ActionResult UploadImage(HttpPostedFileBase file)
    {
        // TODO: your validation goes here, 
        // eg: file != null && file.ContentType.StartsWith("image/") etc...

        var imageUrl = _myAmazonWrapper.UploadImage(file.InputStream);

        return Json(imageUrl);
    }

This action result will receive an HttpPostedFileBase image containing the actual image with content type, file name etc.

The last thing left is the actual initialization of the summernote script:

    $('#summernote').summernote({
        onImageUpload: uploadImages
    });

Where the function uploadImages could be defined as following:

var uploadImages = function (files, editor, $editable) {

    var formData = new FormData();
    formData.append("file", files[0]);

    $.ajax({
        url: "Image/UploadImage",
        data: formData,
        type: 'POST',
        cache: false,
        contentType: false,
        processData: false,
        success: function (imageUrl) {

            if (!imageUrl) {

                // handle error

                return;
            }

            editor.insertImage($editable, imageUrl);
        },
        error: function () {

            // handle error
        }
    });
};

Note that the uploadImage function is not supporting multiple images, for instance you can drag-and-drop images to the summernote widget and in that particular case the "files" parameter will contain multiple images, so just enumerate over them and upload as you please.

Good luck!

Community
  • 1
  • 1
Olivier
  • 571
  • 5
  • 8
3

I had to do this recently in .NET Core.

Here is the code of the action to upload the image to s3 (you need to install AWSSDK.S3):

[HttpPost]
public async Task<IActionResult> UploadFile(IFormFile file)
{
    try
    {
        if (file != null && file.Length > 0)
        {
            var relativePath = string.Empty;

            using (var client = new AmazonS3Client("awsAccessKeyId", "awsSecretAccessKey", RegionEndpoint.USEast1))
            {
                using (var newMemoryStream = new MemoryStream())
                {
                    file.CopyTo(newMemoryStream);

                    var uploadRequest = new TransferUtilityUploadRequest
                    {
                        InputStream = newMemoryStream,
                        Key = file.FileName,
                        BucketName = "bucketName",
                        CannedACL = S3CannedACL.PublicRead
                    };

                    var fileTransferUtility = new TransferUtility(client);
                    await fileTransferUtility.UploadAsync(uploadRequest);

                    relativePath = "urlS3" + "bucketName" + "/" + file.FileName;
                }
            }

            return Ok(new { FileUrl = relativePath });
        }

        return BadRequest("Select a file");
    }
    catch (Exception exception)
    {
        return BadRequest(exception.Message);
    }
}

Here is the code to put in your view, to override the upload method of summernote:

$('.html-editor').summernote({
    callbacks: {
        onImageUpload: function (files) {
            for (let i = 0; i < files.length; i++) {
                uploadImageToS3ForSummerNote(files[i]);
            }
        }
    }
});

function uploadImageToS3ForSummerNote(file) {
    var url = '@Url.Action("UploadFile", "MyController")';

    formData = new FormData();
    formData.append("file", file);
    $.ajax({
        type: 'POST',
        url: url,
        data: formData,
        cache: false,
        contentType: false,
        processData: false,
        success: function (data) {
            $('.html-editor').summernote('insertImage', data.fileUrl);
        },
        error: function (data) {
            alert(data.responseText);
        }
    });
}
Tiago Ávila
  • 2,737
  • 1
  • 31
  • 34