Client Pay Portal
 kentico logo

Building the Bit-Wizards Media Library Importer for Kentico CMS

Often in developing Kentico sites we will utilize the media library for storage and management of files for a project. This functionality provides a great way to organize and store files and is a great addition to any application. When migrating an existing site to Kentico we encounter an issue of having several media library files to import. This blog details how I created a Kentico module to recursively import files into the site.

 

1. Create the Base Module Code

For the project, there is nothing out of the ordinary for the base module. Kentico provides great documentation to walk you through this process in the developers guide here.
 

Loading the Media Libraries

             //Get the media libraries
             DataSet  dsLibraries = MediaLibraryInfoProvider .GetMediaLibraries("" , null );
             if  (!DataHelper .DataSourceIsEmpty(dsLibraries))
             {
                 //Set the drop down data source to the libraries dataset
                 ddlMediaLibraries.DataValueField = "LibraryID" ;
                 ddlMediaLibraries.DataTextField = "LibraryName" ;
                 ddlMediaLibraries.DataSource = dsLibraries;
                 ddlMediaLibraries.DataBind();
             }

 

2. Add Selectors for the Libraries / Folders

For this project, I decided to allow the utility to function on individual media libraries and/or their nested folders. A user selects a media library to import from, then chooses the desired “root” folder to import. The user can also select whether to import the single folder, or subfolders beneath the selected item. There is also an option to allow selecting the “root” media library folder, which in conjunction with the “Include Subfolders” option would allow an entire media library to be imported at once.
 

Loading the Media Library Folders

//Get the selected library id
             int  iLibraryID = Convert .ToInt32(ddlMediaLibraries.SelectedValue.ToString());
             if  (iLibraryID > 0)
             {
                 MediaLibraryInfo  med = MediaLibraryInfoProvider .GetMediaLibraryInfo(iLibraryID);
                 if  (med != null )
                 {
                     //Build up the file path to media library folder
                     string  strFilePath = Server.MapPath("~" );
                     strFilePath = strFilePath + "\\\\"  + CMSContext .CurrentSiteName + "\\\\media\\\\"  + med.LibraryFolder;
                     DirectoryInfo [] dir = new  DirectoryInfo (strFilePath).GetDirectories();
                     //Clear the current folders
                     ddlMediaLibraryFolders.Items.Clear();
                     //Add the first item for the root
                     ddlMediaLibraryFolders.Items.Add(new  ListItem ("--Media Library Root--" , "" ));
                     //Load the folders into the folder drop down
                     foreach  (DirectoryInfo  dirSub in  dir)
                     {
                         ddlMediaLibraryFolders.Items.Add(new  ListItem (dirSub.Name, dirSub.Name));
                     }
                 }
             }

3. Add the Magic

The real functionality of the module comes in how it recursively reads through and imports files. This is achieved by leveraging Kentico APIs and custom functionality. I started with Kentico’s existing code as a base and modified it for my needs.
 

Tip

The media import process needs files without spaces in order to complete the process properly. The module will rename files by replacing spaces with dashes as it works through the files.

 

Importing Files

strFullPath = fileRoot.FullName;
                         //Make sure the file name does not contain spaces
                         if  (fileRoot.FullName.IndexOf(" " ) > -1)
                         {
                             //Rename the file to prevent an error due to spaces in file names
                             CMS.IO.File .Move(fileRoot.FullName.ToString(), fileRoot.FullName.ToString().Replace(" " , "-" ));
                             strFullPath = fileRoot.FullName.Replace(" " , "-" );
                         }
 
 
                         try
                         {
                             //Create the new Media File object
                             //This call will generate an exception if the file already exists
                             MediaFileInfo  fileInfo = new  MediaFileInfo (strFullPath, iLibraryID, strRoot);
                             fileInfo.FileTitle = fileRoot.Name;
                             fileInfo.FileDescription = fileRoot.Name;
 
 
                             // Save media file info
                             MediaFileInfoProvider .ImportMediaFileInfo(fileInfo);
                             //Add file to list of imported
                             sbImportedFiles.Append("<br />"  + fileInfo.FilePath);
                             fileInfo = null ;
                             iImported += 1;
                         }

Note

The Bit-Wizards Media Library Importer currently is configured to read 2 levels into a media library for importing. This functionality can easily be expanded by adding additional recursion code. This is noted in the source code.
 

4. Add Detailed Reporting

In developing the module, I found it beneficial to know what files were actually being published. I added a small option to record the file path / name of each imported file and the user can choose where or not view this information.
 

Detailed Reporting

//Determine the result output detail level
                 if  (cbDetailedResults.Checked)
                 {
                     SetMessage("Total Imported: "  + iImported.ToString() + "<br />"  + sbImportedFiles.ToString() + "<br />Total Already Imported: "  + iAlreadyImported.ToString() + "<br /><br />Total Skipped: "  + iSkipped.ToString() + "<br />"  + sbSkippedFiles.ToString(), false );
                 }
                 else
                 {
                     SetMessage("Total Imported: "  + iImported.ToString() + "<br /><br />Total Already Imported: "  + iAlreadyImported.ToString() + "<br /><br />Total Skipped: "  + iSkipped.ToString(), false );
                 }

5. Add Error Handling

Every good application has ample error handling in the event of a problem ("Ain't nobody got time for that!"). I added standard Kentico Exception handling and am writing all errors to the Event Log for easy storage and review. If your site is configured to receive error notifications, the module will publish these directly to your account when they occur.
 

Tip

I use Kentico Exception Handling in all of my code due to its ease of implementation and configuration. With the one line of code below you get great exception handling and logging.
 

try 
         {
             if  (strMsg != "" )
             {
                 if  (blnError)
                 {
                     lblMessage.Text = "<h4 style=\\"color: red;\\">"  + strMsg + "</h4>" ;
                 }
                 else 
                 {
                     lblMessage.Text = "<h4>"  + strMsg + "</h4>" ;
                 }
             }
             else 
             {
                 lblMessage.Text = "" ;
             }
         }
         catch  (Exception  ex)
         {
             EventLogProvider .LogException("Bit-Wizards Media Library Importer" , "Exception" , ex);
             SetMessage("There was an error in the module. Please check the event log for details." , true );
         }

Author

Wiz E. Wig, Mascot & Director of Magic
Wiz E. Wig

Director of Magic