Not just integrating but also creating an upload functionality for the editor. It’s pretty straight forward but the documentation on CKEditor website is not so complete so I only managed to create both upload and browse functionality in the browse functionality. If you see picture below, I don’t use the Upload tab of the Image Properties, but it works perfectly.
First, if you don’t know how to do file upload in ASP.NET MVC 2, please don’t be lazy to search around or check this blog post from Phil Haack.
Then, download the latest pack from CKEditor website, here’s the link. I am also using the image processing code from my previous post here.
This post will tell you how to create an upload functionality for CKEditor using ASP.NET MVC 2 so that you can use the tab Image Info when you click on the image icon (the same technique can be used to create file browser and upload functionality).
Create the Controller
I give it a name UploadController, here’s my code sample:
The first Index Action method returns a collection of images in a specified folder and 3 ViewData objects that holds CKEditor variables.
The second Index Action is the actual Post request that uploaded the image we selected. After successful upload I RedirectToAction to the Index method (please read more about PRG pattern) to avoid re-uploading the image by mistake if user refreshes the page.
public class UploadController : Controller
{
#region Images
//
// GET: /Admin/Upload/
public ActionResult Index()
{
ViewData["CKEditorFuncNum"] = Request.QueryString["CKEditorFuncNum"];
ViewData["CKEditor"] = Request.QueryString["CKEditor"];
ViewData["langCode"] = Request.QueryString["langCode"];
var dirPath = Path.Combine(Server
.MapPath("~/Content/UploadImages/" + User.Identity.Name));
if (!Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
}
string[] fileNames = Directory.GetFiles(dirPath);
List<FileInfo> images = new List<FileInfo>();
foreach (string filename in fileNames)
{
FileInfo image = new FileInfo(filename);
images.Add(image);
}
return View(images);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(HttpPostedFileBase file,
string CKEditorFuncNum, string CKEditor, string langCode)
{
if (file.ContentLength > 0)
{
var dirPath = Path.Combine(Server
.MapPath("~/Content/UploadImages/" + User.Identity.Name));
if (!Directory.Exists(dirPath))
{
Directory.CreateDirectory(dirPath);
}
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(dirPath, fileName);
file.SaveAs(path);
}
RouteValueDictionary rvd = new RouteValueDictionary();
rvd.Add("CKEditorFuncNum", CKEditorFuncNum);
rvd.Add("CKEditor", CKEditor);
rvd.Add("langCode", langCode);
return RedirectToAction("Index", rvd);
}
}
Upload Index View
The Index View of UploadController, this is the upload form. Here’s the code sample:
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<List<FileInfo>>" %>
<%@ Import Namespace="System.IO" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Upload Images/Files</title>
<script type="text/javascript"
src="/areas/admin/scripts/ckeditor/ckeditor.js"></script>
</head>
<body>
<form action="/Admin/Upload/Index" method="post"
enctype="multipart/form-data">
<label for="file">Image filename:</label><br />
<input type="file" name="file" id="file" /><br />
<input id="CKEditorFuncNum" name="CKEditorFuncNum" type="hidden"
value="<%: ViewData["CKEditorFuncNum"].ToString() %>" />
<input id="CKEditor" name="CKEditor" type="hidden"
value="<%: ViewData["CKEditor"].ToString() %>" />
<input id="langCode" name="langCode" type="hidden"
value="<%: ViewData["langCode"].ToString() %>" />
<input type="submit" value="Upload" />
</form>
<hr />
<% if (Model.Count > 0)
{
foreach (FileInfo image in Model)
{
string CKEditorUrl = "/content/uploadimages/admin/" + image.Name;
string imageUrl = "/admin/upload/images/" + image.Name;
%>
<a title="<%: image.Name %>" href="javascript:void(0);"
onclick="window.opener.CKEDITOR.tools
.callFunction(<%: ViewData["CKEditorFuncNum"] %>,
'<%: CKEditorUrl %>', '');
window.close();">
<img src="<%: imageUrl %>" border="0"
alt="<%: image.Name %>" width="50" height="50" />
</a>
<% }
} %>
</body>
</html>
Image Thumbnail Viewer
In this example, I use my own thumbnail viewer to generate thumbnail on the fly and render it in the browser using Action method that returns FileStreamResult. Notice the SRC attribute of the image on the picture above is set to “/admin/upload/images/{imagefile}”. Here’s my Action method code sample (see my previous post for the Scale method I’m using):
public ActionResult Images(string id)
{
// So that I don't need to specify another route.
string filename = id;
// Get image filename from Request object.
string photoFolder = Server.MapPath("~/Content/UploadImages/admin");
filename = Path.Combine(photoFolder, filename);
int width = 150; int height = 150;
string bg = "#ffffff";
StreamReader r = new StreamReader(filename);
ImageDrawing thumbnail = ImageDrawing.FromStream(r.BaseStream);
MemoryStream ms = new MemoryStream();
thumbnail = Scale(thumbnail, width, height, bg);
thumbnail.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
byte[] imageByte = ms.ToArray();
ms.Dispose();
thumbnail.Dispose();
r.Dispose();
return File(imageByte, "image/jpeg");
}
CKEditor Initialization and Configuration
The following is my View that initializes CKEditor and the correct configuration for this example to work. This code should be placed inside the Head tag. Notice that this line is important, filebrowserImageBrowseUrl: '/admin/upload', this is where the image browse functionality will appear when you click on image icon.
<asp:ContentID="Content3"ContentPlaceHolderID="HeadContent"runat="server">
<scripttype="text/javascript"src="/areas/admin/scripts/ckeditor/ckeditor.js">
</script>
<scripttype="text/javascript">
window.onload = function() {
CKEDITOR.replace('PostContent',
{
toolbar:
[
// Your toolbaar configuration here. but make sure that
// 'Image' is available.
['JustifyLeft', 'JustifyCenter', 'JustifyRight'],
['Image', 'Flash', 'Table', 'HorizontalRule', 'Smiley'],
['Styles', 'Format', 'Font', 'FontSize'],
],
filebrowserImageBrowseUrl: '/admin/upload',
height : 350,
ignoreEmptyParagraph : true,
htmlEncodeOutput : true
});
};
</script>
</asp:Content>
And this is the Html helper that render textarea that will be converted into CKEditor.
<%:Html.TextAreaFor(model => model.PostContent) %>
The same scenario can also be used in ASP.NET Webforms of course. Try it, and if you have problems, don’t hesitate to ask me.
2941cb58-e23f-45fc-be48-c4a414933438|0|.0
ASP.NET, C#, ASP.NET MVC
ckeditor, ASP.NET, C#, MVC, image processing