atVSG

0011001000110100

وحید امیری مطلق

توسعه دهنده وب و موبایل

آپلود عکس در TinyMCE از طریق ASP.NET MVC 5


asp.net-mvc-tinymce

آپلود عکس از طریق یک  WYSWIYG HTML editor مثل TinyMCE یا CKEditor یک کار خیلی رایج و ضروریه ولی متاسفانه با جستجوی در اینترنت نمیتونید روشی جدید و متناسب با ASP.NET MVC رو که با TinyMCE 4 کار کنه پیدا کنید. البته یک یا دو افزونه ی پولی برای TinyMCE 4 وجود داره ولی راه رایگان نه. (لااقل من پیدا نکردم!)

به همین جهت خودم دست به کار شدم و با روشی که در ادامه توضیح میدم تونستم آپلود عکس رو از طریق ASP.NET MVC5 برای TinyMCE 4.x انجام بدم.

موارد مورد نیاز:

  • یک برنامه ASP.NET MVC نسخه 5 یا بالاتر
  • TinyMCE 4.x (در اینجا منظور نسخه های مختلف سری 4 هست. مثلا 4.2)

برای شروع باید در View مورد نظر یعنی جایی که میخواهیم ویرایشگر TinyMCE به نمایش در بیاد کد زیر رو قرار بدیم:

<script src="@Url.Content("~/Scripts/tinymce/tinymce.js")" type="text/javascript"></script>

<iframe id="form_target" name="form_target" style="display:none"></iframe>
<form id="upload_img_form" action="/admin" target="form_target" method="post" enctype="multipart/form-data" style="width:0; height:0; overflow: hidden; display: none;">
    <input name="file" type="file" onchange="$('#upload_img_form').submit();this.value='';">
</form>

<script type="text/javascript">
    tinymce.init({
        selector: "textarea#editable",
        content_css : '@Url.Content("~/Scripts/tinymce/custom.css")',
        theme: "modern",
        plugins: [
            "advlist autoresize 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 sh4tinymce"
        ],
        toolbar1: "insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image | print preview media | forecolor backcolor emoticons | ltr rtl",
        image_advtab: true,
        autoresize_min_height: 250,
        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') $('#upload_img_form input').click();
        }
    });
</script>

پیشنهاد میکنم تمام کد بالا رو در یک PartialView ذخیره کنید و در View مورد نظر این PartialView رو فراخوانی کنید.

در کد بالا به آدرس فایل ها توجه کنید و اون ها رو مطابق با ساختار برنامه ی خودتون تغییر بدید. حالا باید یک اکشن متود (Action Method) برای یکی از Controller هایمان بنویسیم. کار این اکشن متود دریافت فایل آپلود شده از طریق TinyMCE و ذخیره ی اون و همچنین ارسال پاسخ مناسب به سمت کاربر هست. در اینجا یک Controller ساده مینویسیم که درونش این Action Method مورد نظر ما رو داره:

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
using System.IO;
using System.Threading;

namespace MyWebSite.Controllers
{
    [RoutePrefix("admin")]
    public class AdminHomeController : Controller
    {
        [Route("")]
        [HttpPost]
        public string Upload(HttpPostedFileBase file)
        {
            string path;
            string saveloc = "~/data/Images/";
            string relativeloc = "/data/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>";
        }
    }
	
	public static class ValidateUpload
    {
        public static bool IsImage(this HttpPostedFileBase file)
        {
            if (file.ContentType.Contains("image"))
            {
                return true;
            }

            string[] formats = new string[] { ".jpg", ".png", ".gif", ".jpeg" }; // add more if u like...

            foreach (var item in formats)
            {
                if (file.FileName.Contains(item))
                {
                    return true;
                }
            }

            return false;
        }
    }
}

توضیح این Controller :

اینجا یک Controller (کلاس کنترلر) ساده به اسم AdminHome داریم که مثل بقیه کنترلر های MVC کلاس Controller رو Extend میکنه. درونش فقط یک متود برای آپلود عکس در نظر گرفتیم. این متود فقط به درخواست های POST پاسخ میده و برای Routing اون هم از روش Attribute Routing استفاده کردیم که در MVC 5 اضافه شد. از اون جایی که دقیقا قبل از تعریف کلاس، یک پیشوند برای این Routing این کلاس تعریف کردیم، و Routing خود متود آپلود هم صرفا یک string خالی هست، پس آدرس دسترسی به این متود میشه:

http://example.com/admin

که در اینجا به جای example.com باید دامین خودتون رو قرار بدید. همچنین این مقدار رو در کد HTML فرم TinyMCE هم وارد کردیم. (خط 3)

از روش استاندارد آپلود فایل در ASP.NET MVC استفاده میکنیم. همچنین باید محل ذخیره ی عکس رو در 2 متغیر saveloc و relativeloc تنظیم کنید. اینجا نکته ی قابل توضیحی باقی نمیمونه به جز استفاده از Extension Method به نام IsImage که کلاسش زیر کلاس کنترلر ما تعریف شده و کارش اینه که برسی کنه فایل مورد نظر عکس هست یا نه.

در آخر، در صورت موفق بودن فرایند آپلود و ذخیره عکس، ما یک تکه کد جاوا اسکریپت رو بر میگردونیم. این قسمت باعث میشه که لینک عکسی که تازه آپلود شده به فرم آپلود عکس در TinyMCE بچسبه و همچنین دکمه ی ثبت فشار داده بشه که باعث بسته شدن پتجره ی آپلود عکس و چسبیدن عکس به فرم TextArea در TinyMCE میشه.

و در اینجا کار ما به پایان میرسه!



 برچسب ها: ، ، ، ، ، ، ، ، ، ،

 دیدگاه ها:
سوال یا دیدگاه؟

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *