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 :
  1. User/admin upload image using custom formcontrol
  2. 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-) 
  3. Custom form control will save link to custom table
I will share the code here, and you can test by your self. 
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.

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
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 =)

Popular posts from this blog

Example to disable save as certain file type in SSRS Report Viewer

How to create DataGrid or GridView in JSP - Servlet

Control Webpart Visible/Enable using macro in Kentico