Replace Tokens with My Tokens


To skip the details, jump directly to production ready VB.NET or C# code at the end of this page.

Direct Calls


If you have the source code of the component you want to integrate with and you know My Tokens will always be available you can link directly to avt.MyTokens.Core.dll. To tokenize content the simply make calls to avt.MyToken.MyTokensReplacer.ReplaceTokensAll, that has the following prototype:


VB.NET

 
Shared Function ReplaceTokensAll( _
ByVal strSourceText As String, _
ByVal cUser As UserInfo, _
ByVal dbgMsg As Boolean, _
ByVal cModule As ModuleInfo) As String

C#

 
static string ReplaceTokensAll(
string strSourceText,
UserInfo cUser,
bool dbgMsg,
ModuleInfo cModule
);


VB.NET

Invoking MyTokens directly outside of Module scope:

    strContent = avt.MyTokens.MyTokensReplacer.ReplaceTokensAll( _
strContent, _
UserInfo, _
Not DotNetNuke.Common.Globals.IsTabPreview(), _
Nothing
)

Invoking MyTokens directly from Module scope - note the additional parameter:

    strContent = avt.MyTokens.MyTokensReplacer.ReplaceTokensAll( _
strContent, _
UserInfo, _
Not DotNetNuke.Common.Globals.IsTabPreview(), _
ModuleSettings _
)

C#

Invoking MyTokens directly outside of Module scope:

    strContent = avt.MyTokens.MyTokensReplacer.ReplaceTokensAll(
strContent,
UserInfo,
!DotNetNuke.Common.Globals.IsTabPreview(),
null
);

Invoking MyTokens directly from Module scope - note the additional parameter:

    
strContent = avt.MyTokens.MyTokensReplacer.ReplaceTokensAll(
strContent,
UserInfo,
!DotNetNuke.Common.Globals.IsTabPreview(),
ModuleSettings
);

Using Reflection


Most often, you can't rely on MyTokens being installed. Using the code above would cause a compiler error since the type is not known. It's desirable that token replacement runs only when MyTokens is installed and reverts to a default behavior when it's not.


VB.NET

Invoking MyTokens using reflection outside of Module scope

strContent =
DotNetNuke.Framework.Reflection.CreateType("avt.MyTokens.MyTokensReplacer").InvokeMember( _
"ReplaceTokensAll", _
System.Reflection.BindingFlags.InvokeMethod, _
Nothing, _
Nothing, _
New [Object]() { _
strContent, _
UserInfo, _
Not DotNetNuke.Common.Globals.IsTabPreview(), _
Nothing
} _
)

Invoking MyTokens using reflection from Module scope - note the additional parameter

strContent =
DotNetNuke.Framework.Reflection.CreateType("avt.MyTokens.MyTokensReplacer").InvokeMember( _
"ReplaceTokensAll", _
System.Reflection.BindingFlags.InvokeMethod, _
Nothing, _
Nothing, _
New [Object]() { _
strContent, _
UserInfo, _
Not DotNetNuke.Common.Globals.IsTabPreview(), _
ModuleConfiguration _
} _
)

C#

Invoking MyTokens using reflection outside of Module scope

strContent =
DotNetNuke.Framework.Reflection.CreateType("avt.MyTokens.MyTokensReplacer").InvokeMember(
"ReplaceTokensAll",
System.Reflection.BindingFlags.InvokeMethod,
null,
null,
new object[] {
strContent,
UserInfo,
!DotNetNuke.Common.Globals.IsTabPreview(),
null
}
).ToString();

Invoking MyTokens using reflection from Module scope - note the additional parameter

strContent =
DotNetNuke.Framework.Reflection.CreateType("avt.MyTokens.MyTokensReplacer").InvokeMember(
"ReplaceTokensAll",
System.Reflection.BindingFlags.InvokeMethod,
null,
null,
new object[] {
strContent,
UserInfo,
!DotNetNuke.Common.Globals.IsTabPreview(),
ModuleSettings
}
).ToString();

Don't forget to encapsulate this code inside try.. catch statements. Could be that MyTokens is not installed or there is an exception thrown that you'll need to handle.

Production Ready Code


In practice, the solution needs to take into account other factors such as minimizing the overhead of using reflection or reverting to a default behavior.

The function below has the following features:

  1. Uses reflection method so if MyTokens is not installed the website runs normally.
  2. Can be called both from Module scope and from other components (Skin Objects, Services, Http Handlers, etc).
  3. Implements caching so overhead that comes from reflection is eliminated
  4. Reverts to standard DotNetNuke token replacement when MyTokens is not installed
  5. Code can be used as it is, copy paste the function and the includes. Then, invoke it whenever you need token replacement. It's recommended to include the method in a Business Controller Class so it's visible to all controls.
  6. It's Thread Safe


VB.NET Complete Code Sample

    
Imports System.Web
Imports DotNetNuke.Entities.Modules
Imports System.Reflection

' ................................

' replace tokens in a module
strContent = Tokenize(strContent, ModuleConfiguration, False, True)

' replace tokens outside of a module
strContent = Tokenize(strContent, Nothing
, False, True)

' ................................

Public Shared Function Tokenize(strContent As String, modInfo As DotNetNuke.Entities.Modules.ModuleInfo, currentUser as DotNetNuke.Entities.Users.UserInfo, forceDebug As Boolean, bRevertToDnn As Boolean) As String
	Dim cacheKey_Installed As String = "avt.MyTokens2.Installed"
	Dim cacheKey_MethodReplace As String = "avt.MyTokens2.MethodReplace"

	Dim bMyTokensInstalled As String = "no"
	Dim methodReplace As System.Reflection.MethodInfo = Nothing

	Dim bDebug As Boolean = forceDebug
	If Not bDebug Then
		Try
			bDebug = Not DotNetNuke.Common.Globals.IsTabPreview()
		Catch
		End Try
	End If

	SyncLock GetType(DotNetNuke.Services.Tokens.TokenReplace)
		' first, determine if MyTokens is installed
		If HttpRuntime.Cache.[Get](cacheKey_Installed) Is Nothing Then

			' check again, maybe current thread was locked by another which did all the work
			If HttpRuntime.Cache.[Get](cacheKey_Installed) Is Nothing Then

				' it's not in cache, let's determine if it's installed
				Try
					Dim myTokensRepl As Type = DotNetNuke.Framework.Reflection.CreateType("avt.MyTokens.MyTokensReplacer", True)
					If myTokensRepl Is Nothing Then
						Throw New Exception()
					End If
					' handled in catch
					bMyTokensInstalled = "yes"

					' we now know MyTokens is installed, get ReplaceTokensAll methods
					methodReplace = myTokensRepl.GetMethod("ReplaceTokensAll", System.Reflection.BindingFlags.[Public] Or System.Reflection.BindingFlags.[Static], Nothing, System.Reflection.CallingConventions.Any, New Type() {GetType(String), GetType(DotNetNuke.Entities.Users.UserInfo), GetType(Boolean), GetType(DotNetNuke.Entities.Modules.ModuleInfo)}, Nothing)

					If methodReplace Is Nothing Then
						' this shouldn't really happen, we know MyTokens is installed
						Throw New Exception()

					End If
				Catch
					bMyTokensInstalled = "no"
				End Try

				' cache values so next time the funciton is called the reflection logic is skipped
				HttpRuntime.Cache.Insert(cacheKey_Installed, bMyTokensInstalled)
				If bMyTokensInstalled = "yes" Then
					HttpRuntime.Cache.Insert(cacheKey_MethodReplace, methodReplace)
				End If
			End If
		End If
	End SyncLock

	bMyTokensInstalled = HttpRuntime.Cache.[Get](cacheKey_Installed).ToString()
	If bMyTokensInstalled = "yes" Then
		methodReplace = DirectCast(HttpRuntime.Cache.[Get](cacheKey_MethodReplace), System.Reflection.MethodInfo)
		If methodReplace Is Nothing Then
			HttpRuntime.Cache.Remove(cacheKey_Installed)
			Return Tokenize(strContent, modInfo, forceDebug, bRevertToDnn)
		End If
	Else
		' if it's not installed return string or tokenize with DNN replacer
		If Not bRevertToDnn Then
			Return strContent
		Else
			Dim dnnTknRepl As New DotNetNuke.Services.Tokens.TokenReplace()
			dnnTknRepl.AccessingUser = currentUser
			dnnTknRepl.DebugMessages = bDebug
			If modInfo IsNot Nothing Then
				dnnTknRepl.ModuleInfo = modInfo
			End If

			' MyTokens is not installed, execution ends here
			Return dnnTknRepl.ReplaceEnvironmentTokens(strContent)
		End If
	End If

	' we have MyTokens installed, proceed to token replacement
	Return DirectCast(methodReplace.Invoke(Nothing, New Object() {strContent, currentUser, bDebug, modInfo}), String)

End Function

 

C# Complete Code Sample

 

using System.Web;
using DotNetNuke.Entities.Modules;
using System.Reflection;

// ................................

// replace tokens in a module
strContent = Tokenize(strContent, ModuleConfiguration, UserInfo, PortalId);

// replace tokens outside of a module
strContent = Tokenize(strContent, null
, UserController.GetCurrentUserInfo(), PortalController.GetCurrentPortalSettings().PortalId);
    // replace tokens outside of an HTTP context (from a scheduled task for example)
strContent = Tokenize(strContent, null
, null, -1);

// ................................

public static string Tokenize(string strContent, DotNetNuke.Entities.Modules.ModuleInfo modInfo, DotNetNuke.Entities.Users.UserInfo user, int portalId, bool forceDebug = false, bool bRevertToDnn = true) { string cacheKey_Installed = "avt.MyTokens2.Installed"; string cacheKey_MethodReplace = "avt.MyTokens2.MethodReplace"; string bMyTokensInstalled = "no"; System.Reflection.MethodInfo methodReplace = null; bool bDebug = forceDebug; if (!bDebug) { try { bDebug = DotNetNuke.Common.Globals.IsEditMode(); } catch { } } lock (typeof(DotNetNuke.Services.Tokens.TokenReplace)) { // first, determine if MyTokens is installed if (HttpRuntime.Cache.Get(cacheKey_Installed) == null) { // check again, maybe current thread was locked by another which did all the work if (HttpRuntime.Cache.Get(cacheKey_Installed) == null) { // it's not in cache, let's determine if it's installed try { Type myTokensRepl = DotNetNuke.Framework.Reflection.CreateType("avt.MyTokens.MyTokensReplacer", true); if (myTokensRepl == null) throw new Exception(); // handled in catch bMyTokensInstalled = "yes"; // we now know MyTokens is installed, get ReplaceTokensAll methods methodReplace = myTokensRepl.GetMethod( "ReplaceTokensAll", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, System.Reflection.CallingConventions.Any, new Type[] { typeof(string), typeof(DotNetNuke.Entities.Users.UserInfo), typeof(bool), typeof(DotNetNuke.Entities.Modules.ModuleInfo) }, null ); if (methodReplace == null) { // this shouldn't really happen, we know MyTokens is installed throw new Exception(); } } catch { bMyTokensInstalled = "no"; } // cache values so next time the funciton is called the reflection logic is skipped HttpRuntime.Cache.Insert(cacheKey_Installed, bMyTokensInstalled); if (bMyTokensInstalled == "yes") { HttpRuntime.Cache.Insert(cacheKey_MethodReplace, methodReplace); } } } } bMyTokensInstalled = HttpRuntime.Cache.Get(cacheKey_Installed).ToString(); if (bMyTokensInstalled == "yes") { methodReplace = (System.Reflection.MethodInfo)HttpRuntime.Cache.Get(cacheKey_MethodReplace); if (methodReplace == null) { HttpRuntime.Cache.Remove(cacheKey_Installed); return Tokenize(strContent, modInfo, user, portalId, forceDebug, bRevertToDnn); } } else { // if it's not installed return string or tokenize with DNN replacer if (!bRevertToDnn) { return strContent; } else { DotNetNuke.Services.Tokens.TokenReplace dnnTknRepl = new DotNetNuke.Services.Tokens.TokenReplace(); dnnTknRepl.AccessingUser = DotNetNuke.Entities.Users.UserController.GetCurrentUserInfo(); dnnTknRepl.User = user ?? DotNetNuke.Entities.Users.UserController.GetCurrentUserInfo(); dnnTknRepl.DebugMessages = bDebug; if (modInfo != null) dnnTknRepl.ModuleInfo = modInfo; // MyTokens is not installed, execution ends here return dnnTknRepl.ReplaceEnvironmentTokens(strContent); } } // quick hack to pass a portal id to My Tokens if (modInfo == null && portalId != -1) { modInfo = new DotNetNuke.Entities.Modules.ModuleInfo() { PortalID = portalId }; } // we have MyTokens installed, proceed to token replacement return (string)methodReplace.Invoke( null, new object[] { strContent, user ?? DotNetNuke.Entities.Users.UserController.GetCurrentUserInfo(), bDebug, modInfo } ); }