Fun with Telerik Rad Controls (Part 2/5)

by ManniAT 11. April 2009 05:30
Technorati-Tags:

In the first part I showed the implementation of the backup logic.

This step I will show how the  telerik RadFileExplorer is used to achieve what I need.
You remember:

  1. Backup functionality (make copies of deleted / overwritten files)
  2. Copy files with drag and drop (the control does a move for this)
  3. Protect files from being deleted
  4. Add server side events when a file / directory is selected (the control is almost pure client Ajax)

The first step is to provide backup functionality.
The control provides a Custom File Content Provider which allows to hook the functionality at file level.

So I derived a class from this provider and overloaded the functions I need.
I also added properties like “BakupEnabled” and “BackupPath”.
As an example (there are more of course) I handled the “DeleteFile” event like this:

Snippet created with CBEnhancer
public override string DeleteFile(string path) {
        if (m_lProtectedFiles.Contains(path, StringComparer.InvariantCultureIgnoreCase)) {
            return ("File is protected and can't be deleted!");
        }
        string strDidBackup = "NO";
        if(BackupEnabled && !string.IsNullOrEmpty(m_strBackupPath))    {    //backup seems to be possible
            strDidBackup= TryToBackup(path);
            if (strDidBackup!=string.Empty) {
                return ("File not deleted because of backup error: " + strDidBackup);
            }
        }
        string strRet = base.DeleteFile(path);
        if (strRet != string.Empty && strDidBackup != "NO") {    //failed to delete - undo backup
            UndoLastBackup();
        }
        return (strRet);
    }

The first thing to notice here is the base function. It deletes the file – and if an error occurs it returns the error message as string.
The control then displays this error message via alert.

Since communication is done via strings I do the same. If the flag “BackupEnabled” is set and if there is also a valid backup path I try to backup the file.
This can fail due to many reasons – if it fails – I report the error and return – no delete happens.

If it works – the content of strDidBackup changes from NO to string.Empty.
Next (or first if backup was disabled) I call the base class to delete the file.
This can also fail – if it fail I undo my backup.

Simple and easy – as the code to backup the file:

private string TryToBackup(string path) {
    m_strLastBackupSource = null;    //use these strings to enable an undo later
    m_strLastBackupDestination = null;
    m_strLastBackupSource = HttpContext.Current.Server.MapPath(path);
    if (!File.Exists(m_strLastBackupSource)) {
        return ("File not found");
    }
    string strBackupName = BackupEntry.EncodeFileURL(path);
    if (strBackupName == null) {
        return ("Could not encode filename");
    }
    m_strLastBackupDestination = Path.Combine(m_strBackupPath, strBackupName);
    try {
        File.Copy(m_strLastBackupSource, m_strLastBackupDestination);
        return (string.Empty);
    }
    catch (Exception eX) {
        return (eX.Message);
    }
}

Remember the paths – check for existence of the file – and finally try to copy it.

Since this is done (in the same kind for other functions) point one was finished – and the next step is was to implement  the “File Protect” functionality.

This was also not to hard – I simply added a list of the protected files and change the DelteFile method to this:

public override string DeleteFile(string path) {
    if (m_lProtectedFiles.Contains(path, StringComparer.InvariantCultureIgnoreCase)) {
            return ("File is protected and can't be deleted!");
       }
     string strDidBackup = "NO";
   if(BackupEnabled && !string.IsNullOrEmpty(m_strBackupPath))    {    //and so on…..

 

Since Windows is not case sensitive at the file system I compare the thing case insensitive.
If the list contains a protected file I simply return with an “Error message”. Now about the parameters – how to pass them to the file system provider?
We have an Ajax control which creates the file system provider when needed. So the idea to pass in the settings via constructor is not possible – the telerik RadFileExplorer  calls the constructor and
not my usercontrol.

But the settings are done via parameters to my usercontrol. Of course there could be a way to handle the things "somewhere in a page event” where everything meets – but I decided to go a simple way.
I created a helper class which holds the settings – instantiated it in PageLoad and stored it in a Session variable.

XManagerSettings xSettings = Session["MGSettings"] as XManagerSettings;
if (xSettings == null) {
    xSettings = new XManagerSettings();
    Session["MGSettings"] = xSettings;
    TryToSetManagerSettings();
}
    

So now I have my settings in a session variable – and “TryToSetManagerSettings” simply tries to transfer the usercontrol properties to the manager Settings. This is also done when a property is changed – therefore the try in the function name :)

Snippet created with CBEnhancer
/// <summary>
/// tries to transfer the current settings to the manager (if one is bound)
/// </summary>
private void TryToSetManagerSettings() {
    XManagerSettings xSettings = Session["MGSettings"] as XManagerSettings;
    if (xSettings != null) {
        xSettings.BackupURL = m_strBackupURL;
        xSettings.ProtectedFiles = m_strProtectedFiles;
        if (!string.IsNullOrEmpty(m_strDoCopy)) {
            if (m_strDoCopy.ToUpper() == "TRUE" || m_strDoCopy == "1") {
                xSettings.DoCopy = true;
            }
            else if (m_strDoCopy.ToUpper() == "FALSE" || m_strDoCopy == "0") {
                xSettings.DoCopy = false;
            }
        }
        if (!string.IsNullOrEmpty(m_strBackupEnabled)) {
            if (m_strBackupEnabled.ToUpper() == "TRUE" || m_strBackupEnabled == "1") {
                xSettings.BackupEnabled = true;
            }
            else if (m_strBackupEnabled.ToUpper() == "FALSE" || m_strBackupEnabled == "0") {
                xSettings.BackupEnabled = false;
            }
        }
    }
}

The interesting part in this function the handling of the “boolean” properties. The reason for the False (0) checks is that I also provide settings via web.config. The settings on the usercontrol override them – but if there are none I avoid to set something.

When the telerik RadFileExplorer instantiates the File Content Provider I can access those settings in the constructor.

Snippet created with CBEnhancer
public MyFileSystemProvider(HttpContext hContext, string[] searchPatterns, string[] viewPaths, string[] uploadPaths, string[] deletePaths, string selectedURL, string selectedTag) :
    base(hContext, searchPatterns, viewPaths, uploadPaths, deletePaths, selectedURL, selectedTag) {
    //take defaults from web.config
    m_bDoCopy = m_bDefaultDoCopy;
    BackupURL = m_strDefaultBackupURL;
    BackupEnabled = m_bDefaultBackupEnabled;
    m_lProtectedFiles = new List<string>();
    XManagerSettings xSettings = hContext.Session["MGSettings"] as XManagerSettings;
    if (xSettings != null) {
        xSettings.FSProvider = this;    //assume it will set DoCopy, BackupEnabled, protectedFiles and BackupURL with this call if needed
    }
}

The final “trick” is done with xSettings.FSProvider=this – this enables the settings class to set values in the File Content Provider.
Although this approach may look a bit dirty – it save me a lot of time messing around with timings (what is instantiated when).

Conclusion – my usercontrol gets the settings. These settings are transferred to a settings class.
This settings class is passed to FileSystemProvider – and the FSP “registers” itself with the settings.
So the settings act as a “man in the middle” – which is useful in cases where the  telerik RadFileExplorer is hosted in a page or somewhere else instead of in a usercontrol.

The last thing here is to implement the “copy instead of move”. Also a simple thing:

public override string MoveFile(string path, string newPath) {
    if (m_lProtectedFiles.Contains(path, StringComparer.InvariantCultureIgnoreCase) &&
!DoCopy) { //allow move if it is a copy return ("File is protected and can't be moved!"); } string strRet = base.MoveFile(path, newPath); if (!DoCopy || strRet != string.Empty){//no need to copy - or error in MoveFile run away :) return strRet; } //copy the file back to the original location string strSource=HttpContext.Current.Server.MapPath(path); string strDestination=HttpContext.Current.Server.MapPath(newPath); File.Copy(strDestination, strSource); return strRet; }

This function does first check (protect files) if we will copy and if the file is protected.
A protected file must only be moved if copy is active.

Next we let the original handler do it’s work – and if Copy is set we simply copy the file back to it’s original location.

So there is only one point left – Events for the control. I’ll describe this in the next section.

Tags:

telerik

Comments (2) -

11/22/2010 8:00:49 AM #

aluminium

I have been trying to acces this site for a while. I was using Chrome then when I tried Safari, it worked just great? Just wanted to bring this to your attention. This is really good website. I have a few myself. I really admire your design. I know this is off topic but,did you make this layout yourself,or purchase from somewhere?

aluminium United States | Reply

11/22/2010 11:25:25 AM #

ManniAT

Just to be clear (I'm a bit confused about " I was using Chrome then when I tried Safari, it worked just great?"):
Do you have any layout problems using chrome?
I tried this layout with: Safari, Chrome, Opera, FF, IE (latest versions) and it looks (almost) similar in every browser.
The mainpage http://manniat.pp-p.net is done by myself.
Here I use http://www.dotnetblogengine.net/ 1.5 - slightly adapted.
And I built a design template which (pretty easy) uses the same (a copy) master page
as int the main site and also uses the same CSS styles.
The only difference - in the mainsite I use "fluid" (top fully files) and
here I use a "block" (fixed width) layout.

About the design in general. The start was inspired by a "VS 2005 Starter Kit".
I first tryed to use it - but it didn't really fit my needs. So I gave this up and created the design by myself.
I only kept the the idea of the "top block" (Title, Description, Navigation, Image-Element).

Last not least - navigation here come from blogengine and on the mainsite,
I use a telerik http://www.telerik.com menu wich retrives the items from a web.sitemap datasource.

ManniAT Austria | Reply

Pingbacks and trackbacks (1)+

Add comment




  Country flag
biuquote
  • Comment
  • Preview
Loading


Powered by BlogEngine.NET 2.0.0.0