Kentico 8.1 - Custom Upload Form Control [Solved to support custom table to store image/binary stream data]
Kentico is a powerful CMS engine that allow you to developed portal very fast. But when you have a really big data such as (10,000 above), you may need to think a different way to store the data(Not put all document as a Page Menu Item).
I have heard kentico have test their product for 100K document. But from my experience using shared server, it is cause a lot of painful if you want to expand the node in your page module, and even very slow to load the data.(That is my situation).
So after all, I have decided to developed a "Custom Upload FormControl" to make Custom table support for upload files/media. This implementation is quite tricky because the custom formcontrol just store link to custom table field and it will store the image into media library folder. Look at the flow below :
Before That you need to create Media Library name "UserMedia".
Note : This is just example only, the code may have a bug. Use it at your own risk.
By Mohd Zulkamal
NOTE : – If You have Found this post Helpful, I will appreciate if you can Share it on Facebook, Twitter and Other Social Media Sites. Thanks =)
I have heard kentico have test their product for 100K document. But from my experience using shared server, it is cause a lot of painful if you want to expand the node in your page module, and even very slow to load the data.(That is my situation).
So after all, I have decided to developed a "Custom Upload FormControl" to make Custom table support for upload files/media. This implementation is quite tricky because the custom formcontrol just store link to custom table field and it will store the image into media library folder. Look at the flow below :
- User/admin upload image using custom formcontrol
- Custom formcontrol check folder in media library, if not exist, create media library folder.(Each user will have their own folder so in future if you want to limit the folder size, you can modified the code to check folder file is user have exceed their storage - quite cool ha B-)
- Custom form control will save link to custom table
I will share the code here, and you can test by your self.
Note : This is just example only, the code may have a bug. Use it at your own risk.
ASCX page
<cms:Uploader ID="uploader" runat="server" OnOnDeleteFile="uploader_OnDeleteFile1" OnOnUploadFile="uploader_OnUploadFile1" />
<asp:Button ID="hdnPostback" CssClass="HiddenButton" runat="server" EnableViewState="false" />
Code Behind
using System;
using System.Collections.Generic;
using CMS.Base;
using CMS.DataEngine;
using CMS.DocumentEngine;
using CMS.ExtendedControls;
using CMS.FormControls;
using CMS.FormEngine;
using CMS.Helpers;
using CMS.IO;
using CMS.OnlineForms;
using CMS.SiteProvider;
using CMS.Membership;
using CMS.MediaLibrary;
public partial class CMSFormControls_CustomUploadControl : FormEngineUserControl
{
#region "Constants"
private const string FORBIDDEN_EXTENSIONS = ";aspx;ashx;asp;cshtml;vbhtml;";
#endregion
#region "Variables"
private string mValue;
private UserInfo updateUser;
#endregion
#region "Properties"
/// <summary>
/// Gets or sets the enabled state of the control.
/// </summary>
public override bool Enabled
{
get
{
return uploader.Enabled;
}
set
{
uploader.Enabled = value;
}
}
/// <summary>
/// GetCurrent User
/// </summary>
public UserInfo UpdateUser
{
get
{
if (updateUser == null)
{
updateUser = UserInfoProvider.GetUserInfo(MembershipContext.AuthenticatedUser.UserName);
}
return updateUser;
}
set
{
updateUser = value;
}
}
/// <summary>
/// Gets or sets form control value.
/// </summary>
public override object Value
{
get
{
if (String.IsNullOrEmpty(mValue) || (mValue == Guid.Empty.ToString()))
{
return null;
}
return mValue;
}
set
{
mValue = ValidationHelper.GetString(value, String.Empty);
}
}
#endregion
#region "Methods"
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (FieldInfo != null)
{
uploader.ID = FieldInfo.Name;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!RequestHelper.IsPostBack())
{
Session["AlreadyDone"] = false;
}
// Apply styles
if (!String.IsNullOrEmpty(ControlStyle))
{
uploader.Attributes.Add("style", ControlStyle);
ControlStyle = null;
}
if (!String.IsNullOrEmpty(CssClass))
{
uploader.CssClass = CssClass;
CssClass = null;
}
// Set image auto resize configuration
if (FieldInfo != null)
{
int uploaderWidth;
int uploaderHeight;
int uploaderMaxSideSize;
ImageHelper.GetAutoResizeDimensions(FieldInfo.Settings, SiteContext.CurrentSiteName, out uploaderWidth, out uploaderHeight, out uploaderMaxSideSize);
uploader.ResizeToWidth = uploaderWidth;
uploader.ResizeToHeight = uploaderHeight;
uploader.ResizeToMaxSideSize = uploaderMaxSideSize;
}
CheckFieldEmptiness = false;
}
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
// Hide hidden button
hdnPostback.Style.Add("display", "none");
// Do no process special actions if there is no form
if (Form == null)
{
return;
}
// ItemValue is GUID or file name (GUID + extension) when working with forms
if (mValue.LastIndexOfCSafe(".") == -1)
{
Guid fileGuid = ValidationHelper.GetGuid(Value, Guid.Empty);
if (fileGuid != Guid.Empty)
{
}
//Response.Write(fileGuid.ToString());
}
else
{
uploader.CurrentFileName = (Form is BizForm) ? ((BizForm)Form).GetFileNameForUploader(mValue) : FormHelper.GetOriginalFileName(mValue);
// Get media library
MediaLibraryInfo library = MediaLibraryInfoProvider.GetMediaLibraryInfo("UserMedia", SiteContext.CurrentSiteName);
if (UpdateUser == null)
{
UpdateUser = UserInfoProvider.GetUserInfo(MembershipContext.AuthenticatedUser.UserName);
}
if (library != null)
{
string folderName = "Custom" + String.Join(" ", SqlHelper.GetSafeQueryString(updateUser.UserName).Split(' '));
string fileName = uploader.CurrentFileName;
string filePath = "~/" + SiteContext.CurrentSiteName + "/media/" + library.LibraryFolder + "/" + folderName;
string fullPath = filePath + "/" + fileName;
uploader.CurrentFileUrl = fullPath;
}
}
if (Form != null)
{
// Register post back button for update panel
if (Form.ShowImageButton && Form.SubmitImageButton.Visible)
{
ControlsHelper.RegisterPostbackControl(Form.SubmitImageButton);
}
else if (Form.SubmitButton.Visible)
{
ControlsHelper.RegisterPostbackControl(Form.SubmitButton);
}
}
}
/// <summary>
/// Returns true if user control is valid.
/// </summary>
public override bool IsValid()
{
// Check allow empty
if ((FieldInfo != null) && !FieldInfo.AllowEmpty && ((Form == null) || Form.CheckFieldEmptiness))
{
if (String.IsNullOrEmpty(uploader.CurrentFileName) && (uploader.PostedFile == null))
{
// Error empty
ValidationError += ResHelper.GetString("BasicForm.ErrorEmptyValue");
return false;
}
}
// Test if file has allowed file-type
if ((uploader.PostedFile != null) && (!String.IsNullOrEmpty(uploader.PostedFile.FileName.Trim())))
{
string customExtension = ValidationHelper.GetString(GetValue("extensions"), String.Empty);
string extensions = null;
if (CMSString.Compare(customExtension, "custom", true) == 0)
{
extensions = ValidationHelper.GetString(GetValue("allowed_extensions"), String.Empty);
}
string ext = Path.GetExtension(uploader.PostedFile.FileName);
if (!IsFileTypeAllowed(ext, extensions))
{
// Add global allowed file extensions from Settings
if (extensions == null)
{
extensions += ";" + SettingsKeyInfoProvider.GetStringValue(SiteContext.CurrentSiteName + ".CMSUploadExtensions");
}
extensions = (extensions.TrimStart(';')).TrimEnd(';').ToLowerCSafe();
// Remove forbidden extensions
var allowedExtensions = new List<string>(extensions.Split(';'));
foreach (string extension in FORBIDDEN_EXTENSIONS.Split(';'))
{
if (allowedExtensions.Contains(extension))
{
allowedExtensions.Remove(extension);
}
}
ValidationError += string.Format(ResHelper.GetString("BasicForm.ErrorWrongFileType"), ext.TrimStart('.'), string.Join(", ", allowedExtensions));
return false;
}
}
return true;
}
protected void uploader_OnUploadFile1(object sender, EventArgs e)
{
if (!(bool)Session["AlreadyDone"] && IsValid())
{
// Get media library
MediaLibraryInfo library = MediaLibraryInfoProvider.GetMediaLibraryInfo("UserMedia", SiteContext.CurrentSiteName);
if (UpdateUser == null)
{
UpdateUser = UserInfoProvider.GetUserInfo(MembershipContext.AuthenticatedUser.UserName);
}
if (library != null)
{
// Prepare the parameters
string folderName = "Custom" + String.Join(" ", SqlHelper.GetSafeQueryString(updateUser.UserName).Split(' '));
string fileName = uploader.PostedFile.FileName;
string filePath = "~/" + SiteContext.CurrentSiteName + "/media/" + library.LibraryFolder + "/" + folderName;
string fullPath = filePath + "/" + fileName;
//check directory exist, if not create it
if (!Directory.Exists(filePath))
{
MediaLibraryInfoProvider.CreateMediaLibraryFolder(SiteContext.CurrentSiteName, library.LibraryID, "Custom" + String.Join(" ", SqlHelper.GetSafeQueryString(updateUser.UserName).Split(' ')), false);
}
//save file
uploader.PostedFile.SaveAs(Server.MapPath(fullPath));
// Create new media file object
MediaFileInfo mediaFile = new MediaFileInfo(uploader.PostedFile, library.LibraryID,folderName);
// Create file info
FileInfo file = FileInfo.New(Server.MapPath(fullPath));
if (file != null)
{
// Set the properties
mediaFile.FileName = file.Name.Split('.')[0];
mediaFile.FileTitle = file.Name.Split('.')[0];
mediaFile.FileDescription = "File Description";
mediaFile.FilePath = folderName + "/" + file.Name;
mediaFile.FileExtension = file.Extension;
mediaFile.FileMimeType = uploader.PostedFile.ContentType;
mediaFile.FileSiteID = SiteContext.CurrentSiteID;
mediaFile.FileLibraryID = library.LibraryID;
mediaFile.FileSize = file.Length;
// Create the media file
MediaFileInfoProvider.SetMediaFileInfo(mediaFile);
Value = mediaFile.FilePath;
File.Delete(Server.MapPath(fullPath));
Session["AlreadyDone"] = true;
}
}
}
else
{
Session["AlreadyDone"] = false;
}
}
protected void uploader_OnDeleteFile1(object sender, EventArgs e)
{
// Get the media file
MediaFileInfo deleteFile = MediaFileInfoProvider.GetMediaFileInfo(SiteContext.CurrentSiteName, uploader.CurrentFileUrl.Replace("~/<sitename>/media/UserMedia/", ""), null);
if (deleteFile != null)
{
// Delete the media file
MediaFileInfoProvider.DeleteMediaFileInfo(deleteFile);
// Clear CurrentFileName and CurrentFileUrl in uploader
uploader.Clear();
mValue = "";
}
}
#endregion
}
By Mohd Zulkamal
NOTE : – If You have Found this post Helpful, I will appreciate if you can Share it on Facebook, Twitter and Other Social Media Sites. Thanks =)