Extending Redirect Toolkit

In version 1.8.0 we completely rewritten the core architecture to decouple entities from actual implementation. This means that Redirect Toolkit dynamically (at runtime) determines which Condition Types, Operators and Actions to present. There are specified in configuration files located in /DesktopModules/RedirectToolkit/Config folder.
But this also mean it's possible to extend Redirect Toolkit with new Condition Types, Operators and Actions just by implementing an interface and updating the configuration.

Creating new Condition Types

A condition type is a Redirect By... category you see in Add/Edit Rule screen. A condition exposes one ore more properties. It implements ICondition interface that lives in avt.RedirectToolkit.Conditions namespace. You'll have to link add avt.RedirectToolkit.dll as a reference to your project. You can find this assembly in the installation package or in your Website /bin folder.

Below is how we implemented Redirects By Host (in C#). Note that SimpleProperty is an utility class that you can also use in your plugins. It takes care of instantiating appropriate operator and check saved value against the one providing to the constructor.

public class RedirectByHost: ICondition { public bool IsMatch(RedirectConditionInfo condition) { if (HttpContext.Current == null) return false; switch (condition.PropertyName.ToLower()) { case "domain": return new SimpleProperty(condition,                         condition.Definition.Title,                         HttpContext.Current.Request.Url.Host).IsMatch(); case "fullurl": return new SimpleProperty(condition,                         condition.Definition.Title,                         HttpContext.Current.Request.Url.ToString()).IsMatch(); } return false; } public string ToString(RedirectConditionInfo condition) { if (HttpContext.Current == null) return ""; switch (condition.PropertyName.ToLower()) { case "domain": return new SimpleProperty(condition,                         condition.Definition.Title,                         HttpContext.Current.Request.Url.Host).ToString(); case "fullurl": return new SimpleProperty(condition,                         condition.Definition.Title,                         HttpContext.Current.Request.Url.ToString()).ToString(); } return ""; } public List GetItems(ConditionDef condition) { return null; // no list of possible values } }

To test your plugin you have to copy it to your website bin folder and then register into to the Redirect Toolkit configuration file. So go to /Config/Conditions and create a new XML file (better to copy paste an existing file and start from there). Note that the numbers at the beginning of the XML files are only used for sorting - they determine the order they follow when listed in Add/Edit Rule screen.

Most important thing is to think of a code that is unique and short (maximum 10 chars). This is used to link a rule to a definition. After this is done proceed to defining the definitions. Obviously this should be matched with something you implemented in the code to handle them differently. In the example above, there are two properties: domain and fullurl. In the configuration file there are two important things to set: the type (use standard format FullQualifiedTypeName, Assembly Name) and the name of an operators group to use. In our case both properties are of type text so we use __opText. 

More about operators in next section.

Creating New Operators


Redirect Toolkit comes with operators to handle all common scenarios, but at some points you may need to write your own. To create an operator you must write a class that implements IOperator which lives in avt.RedirectToolkit.Operators namespace. You'll have to link add avt.RedirectToolkit.dll as a reference to your project.

Below is how we implemented the Equals operator.

public class Equals : IOperator { public bool IsMatch(OperatorDef opDef, object savedValue, object contextValue) { try { savedValue = savedValue.ToString(); } catch { savedValue = ""; } try { contextValue = contextValue.ToString(); } catch { contextValue = ""; } if (opDef.HasFlag("ignorecase")) { savedValue = savedValue.ToString().ToLower(); contextValue = contextValue.ToString().ToLower(); } bool isMatch = savedValue.ToString() == contextValue.ToString(); if (opDef.HasFlag("not")) { isMatch = !isMatch; } return isMatch; } public string GetName(OperatorDef opDef) { string name = opDef.HasFlag("not") ? "notEquals" : "equals"; if (opDef.HasFlag("ignorecase")) { name += "IgnoreCase"; } return name; } }

To test your plugin you have to copy it to your website bin folder and then register into to the Redirect Toolkit configuration file. So go to /Config/Operators and create a new XML file (better to copy paste an existing file and start from there). Note that the numbers at the beginning of the XML files are only used for sorting - they determine the order they follow when listed in Add/Edit Rule screen.

Note that the most important thing in the xml file is adding the operator to appropriate operator groups which are defined in Types.xml in same folder. Because it's the operators group name you use when declaring which operators a Condition Types supports. An operator can be added to multiple operator groups (in our example, equals can compare both strings and numbers - and complex objects too if they implement ToString in a unique manner).


Creating new Actions

Probably this is the aspect you'll think most about extending. The additional actions are pieces of functionality to run when a redirect matches and before actually redirecting the user. For example Log Redirect, Add/Remove roles, logout user - they're all actions.

To create an operator you must write a class that implements IExecutableAction which lives in avt.RedirectToolkit.Action namespace. You'll have to link add avt.RedirectToolkit.dll as a reference to your project.

Below is how we implemented the DnnLogout action.

public class DnnLogout : IExecutableAction { public void Execute(RedirectRuleInfo rule,             ActionDefinition actDef, string actionData, string redirectToUrl) { UserInfo cUser = UserController.GetCurrentUserInfo(); if (cUser != null && cUser.UserID > 0) { DataCache.ClearUserCache(                     PortalController.GetCurrentPortalSettings().PortalId,                      HttpContext.Current.User.Identity.Name); PortalSecurity objPortalSecurity = new PortalSecurity(); objPortalSecurity.SignOut(); } } public string ToString(RedirectRuleInfo rule,             ActionDefinition actDef, string actionData) { return actDef.Title; } }

To test your plugin you have to copy it to your website bin folder and then register into to the Redirect Toolkit configuration file. So go to /Config/Actions and create a new XML file (better to copy paste an existing file and start from there). Note that the numbers at the beginning of the XML files are only used for sorting - they determine the order they follow when listed in Add/Edit Rule screen.

It's important that in the configuration file you specify a code that is unique and has up to 10 characters. Under execute node put the type of your action in standard format "FullQualifiedTypeName, Assembly Name".
Also note the settings-html node. This makes it possible to provide your own ascx control that will be used in Add/Edit Role screen to gather runtime configuration for your action. The ascx control must implement IActionSettingsCtrl that has methods LoadSettings and SaveSettings. They both operate with a string value which is serialization of the data (you decide the format character delimitation, xml, json, etc).


Comments