How to upload and inject image to tinymce 4 using Asp.net MVC

北战南征 提交于 2021-02-17 13:57:12

问题


So because there is absolutely no modern way of uploading images to tinymce in .net for free, I was thinking of maybe adding a file upload input in html then upload it to server using ajax and then include the file in tinymce editor.

The problem is injecting image to tinymce, I don't know how to...

Is there any way?


回答1:


Ok, Micro$oft or someone else needs to really do something about this, in the mean time here is the result of hours of debugging:

This solution uses direct upload function (already there in Tinymce but disabled by default) and with some jquery hack we inject the image into textarea.

Changing dimensions must be done after injecting the image. In the recent versions of Tinymce they also added some nice image editing tools that also work with this method.

Now the code:

This is the action that needs to be placed in a controller: (Mind the routing)

public string Upload(HttpPostedFileBase file)
    {
        string path;
        string saveloc = "~/Images/";
        string relativeloc = "/Images/";
        string filename = file.FileName;

        if (file != null && file.ContentLength > 0 && file.IsImage())
        {
            try
            {
                path = Path.Combine(HttpContext.Server.MapPath(saveloc), Path.GetFileName(filename));
                file.SaveAs(path);
            }
            catch (Exception e)
            {
                return "<script>alert('Failed: " + e + "');</script>";
            }
        }
        else
        {
            return "<script>alert('Failed: Unkown Error. This form only accepts valid images.');</script>";
        }

        return "<script>top.$('.mce-btn.mce-open').parent().find('.mce-textbox').val('" + relativeloc + filename + "').closest('.mce-window').find('.mce-primary').click();</script>";
    }

And this is the complete code for Tinymce, it will generate a text box and a couple of hidden fields. It will also make an instance of tinymce with some plugins enabled.

    <iframe id="form_target" name="form_target" style="display:none"></iframe>

<form id="my_form" action="/admin" target="form_target" method="post" enctype="multipart/form-data" style="width:0;height:0;overflow:hidden">
    <input name="file" type="file" onchange="$('#my_form').submit();this.value='';">
</form>
<script type="text/javascript">
tinymce.init({
    selector: "textarea",
    theme: "modern",
    plugins: [
        "advlist autolink lists link image charmap print preview hr anchor pagebreak",
        "searchreplace wordcount visualblocks visualchars code fullscreen",
        "insertdatetime media nonbreaking save table contextmenu directionality",
        "emoticons template paste textcolor colorpicker textpattern imagetools"
    ],
    toolbar1: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image",
    toolbar2: "print preview media | forecolor backcolor emoticons | ltr rtl",
    image_advtab: true,
    templates: [
        {title: 'Test template 1', content: 'Test 1'},
        {title: 'Test template 2', content: 'Test 2'}
    ],
    file_browser_callback: function(field_name, url, type, win) {
    if(type=='image') $('#my_form input').click();
}
});
</script>

<textarea id="my_editor" class="mceEditor">This will be an editor.</textarea>

You need to make a folder named "Images" in your project root for uploading images. You also need Tinymce js file and jquery.

Change the action of the form according to your setup!!!

You may also choose to use html helpers. I don't like them. but go ahead and use those instead of this handmade form if you like.

The idea is from here but it was done in python so I rewrote it to work with ASP.NET MVC5 and Latest version of TinyMCE.

I will keep working on this in the next few days and will edit this answer if necessary.




回答2:


I did this in TinyMCE 4.3.10

In tinymce.init, put these options:

paste_data_images: true,
images_upload_url: '/YourController/UploadImage',
images_upload_base_path: '/some/basepath'

In CSharp code:

public ActionResult UploadImage(HttpPostedFileBase file)
{
    file.SaveAs("<give it a name>");
    return Json(new { location = "<url to that file>" });
}

You should be able to copy and paste image to your textarea (strange, drag and drop doesn't work anymore).




回答3:


this is my config for the latest version of tinymce..

File_browser_callback is depreciated

..and it works..this works on copy paste,insert image. I haven't tried with file upload manager yet

         automatic_uploads: true, << auto run your upload script

         images_upload_url: 'ImageUpload', <<your upload, I'm using mvc and I'm routing to "ImageUpload"

        images_reuse_filename:true, << this is where the return json from your code i had a hard time finding this out.  

       file_picker_types: 'image', << type where the upload will appear images dialog,link or file

        //custom file picker       
        file_picker_callback: function (cb, value, meta) {
        var input = document.createElement('input');
        input.setAttribute('type', 'file');
        input.setAttribute('accept', 'image/*');

        // Note: In modern browsers input[type="file"] is functional without 
        // even adding it to the DOM, but that might not be the case in some older
        // or quirky browsers like IE, so you might want to add it to the DOM
        // just in case, and visually hide it. And do not forget do remove it
        // once you do not need it anymore.

        input.onchange = function () {
            var file = this.files[0];

            // Note: Now we need to register the blob in TinyMCEs image blob
            // registry. In the next release this part hopefully won't be
            // necessary, as we are looking to handle it internally.
            var id = 'blobid' + (new Date()).getTime();
            var blobCache = tinymce.activeEditor.editorUpload.blobCache;
            var blobInfo = blobCache.create(id, file);
            blobCache.add(blobInfo);
            console.log(id);
            console.log(blobCache);
            // call the callback and populate the Title field with the file name
            cb(blobInfo.blobUri(), { title: file.name });
            console.log(meta.filetype);



        };

        input.click();


    },



回答4:


I work in a JSF/Java web application and this code in tynymce.init javascript bellow worked fine for me. The pictures are saved in the middle of the text field (I suppose). I guess there's no need for aditional code

tinymce.init({
      selector: "textarea",
      browser_spellcheck: true,
      paste_data_images: true,
      plugins: [
        "advlist autolink autosave link image lists charmap print preview hr anchor pagebreak spellchecker",
        "searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking",
        "table contextmenu directionality template textcolor paste fullpage textcolor colorpicker textpattern"
      ],

      toolbar1: "bold italic underline strikethrough | alignleft aligncenter alignright alignjustify | formatselect fontselect fontsizeselect",
      toolbar2: "cut copy paste | searchreplace | bullist numlist | outdent indent blockquote | undo redo | link unlink anchor image code | insertdatetime preview | forecolor backcolor",
      toolbar3: "table | hr removeformat | subscript superscript | charmap emoticons | print fullscreen | ltr rtl | spellchecker | visualchars visualblocks nonbreaking template pagebreak restoredraft",

      menubar: false,
      image_advtab: true,
      toolbar_items_size: 'small',

      file_picker_callback: function(callback, value, meta) {
          if (meta.filetype == 'image') {
                var inputFile = document.createElement("INPUT");
                inputFile.setAttribute("type", "file");
                inputFile.setAttribute("style","display: none");
                inputFile.click();
                inputFile.addEventListener("change", function() {
                var file = this.files[0];
                var reader = new FileReader();
                reader.onload = function(e) {
                  callback(e.target.result, {
                    alt: ''
                  });
                };
                reader.readAsDataURL(file);
             });
          }
        },

      insertdatetime_dateformat: "%d/%m/%Y",
      insertdatetime_timeformat: "%H:%M:%S",
      language: 'pt_BR',
    });



回答5:


HTML

API_KEY - replace with yours for tinymce Selector - replace MVC Controller in 'Control' Area

  <script src="https://cdn.tiny.cloud/1/API_KEY/tinymce/5/tinymce.min.js"></script>
    <script>
        tinymce.init({
            selector: '#Body',
            menubar: ' edit view insert format tools table',
            toolbar: 'undo redo | bold italic underline strikethrough | fontselect fontsizeselect formatselect | alignleft aligncenter alignright alignjustify | outdent indent |  numlist bullist  | forecolor backcolor removeformat | emoticons | fullscreen  | image media  link | code',
            plugins: 'code importcss  searchreplace autolink   visualblocks visualchars fullscreen image link media   codesample table charmap hr  nonbreaking anchor toc insertdatetime advlist lists  wordcount   imagetools textpattern noneditable   charmap   quickbars  emoticons',
            contextmenu: "link image imagetools table",
            image_advtab: true,
            toolbar_sticky: true,
            images_upload_url: '/Control/Home/UploadImage',
            paste_data_images: true,
        });
    </script>

C#

namespace Project.Areas.Control.Controllers
{
    [Authorize(Roles = "admin")]
    public class HomeController : WebBaseController
    {

        [HttpPost]
        public JsonResult UploadImage(HttpPostedFileBase file)
        {
            var uploadsPath = HostingEnvironment.MapPath($"/uploads");
            var uploadsDir = new DirectoryInfo(uploadsPath);
            if (!uploadsDir.Exists)
                uploadsDir.Create();

            var imageRelativePath = $"/uploads/{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.jpg";
            var imageAbsPath = HostingEnvironment.MapPath(imageRelativePath);
            var imageBytes = file.InputStream.ReadToEnd();
            System.IO.File.WriteAllBytes(imageAbsPath, imageBytes);
            return Json(new { location = imageRelativePath });
        }
.....

Extension Method

public static byte[] ReadToEnd(this Stream input)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                input.CopyTo(ms);
                return ms.ToArray();
            }
        }


来源:https://stackoverflow.com/questions/33617282/how-to-upload-and-inject-image-to-tinymce-4-using-asp-net-mvc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!