KB's

Creating a custom URL Mapping Service

Instead of using the default Domain-Page mapping implementation of the CMS URL Mapping Service, you can create a custom URL Mapping.

The URL Mapping service allows to define different Site Map roots based on the information in the current HTTP Context.

For example, you can map a specific CMS page in the site to a specific Membership User. So when the site is accessed by this user, the mapped CMS page behaves as a root of the site.

Here is the sample implementation:

1. Create UserUrlMappingService class in the ~/App_Code/UserUrlMappingService.cs:
using System.Web; 
using System.Web.Security; 
using Telerik.Cms.Web; 
 
public class UserUrlMappingService : UrlMappingServiceBase 
    protected override string GetKey(HttpContext context) 
    { 
        RolePrincipal principal = context.User as RolePrincipal; 
        if (principal != null
        { 
            return context.User.Identity.Name; 
        } 
        else 
        { 
            // We should check the cookies,  
            // because sometimes this method is called in the BeginRequest (before the user is authenticated). 
            HttpCookie cookie = context.Request.Cookies[FormsAuthentication.FormsCookieName]; 
            if (cookie != null
            { 
                FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value); 
                if (ticket != null
                    return ticket.Name; 
            } 
        } 
 
        return string.Empty; 
    } 


2. Declare the Mapping Service in the web.config and add your mappings:
<cms defaultProvider="Sitefinity" ...> 
    <urlMappings type="Custom" customService="UserUrlMappingService, App_Code"
            <add key="[username]" value="[page_path]" /> 
    </urlMappings> 
    ... 

Where username is the name of the membership user and page_path is the path to the page without extension i.e. page1 or page1/subpage1.

Additionally, you can declare custom parameters for the mapping elements in the collection, and later access them for specific SiteMap node if it belongs to that mapping configuration.
For example, lets say that you have 2 users (user1 and user2) and you want to define different Site Map roots for them (page1 and page2). Also, you want to dynamically load different themes when the users access any page under their roots. Here is the implementation:

1. UserUrlMappingService:
using System.Web; 
using System.Web.Security; 
using Telerik.Cms.Web; 
using Telerik.Cms.Configuration; 
 
public class UserUrlMappingService : UrlMappingServiceBase 
    protected override UrlMappingInfo CreateMappingInfoItem(UrlMappingElement mappingElement) 
    { 
        return new UserUrlMappingInfo(mappingElement); 
    } 
 
    protected override string GetKey(HttpContext context) 
    { 
        RolePrincipal principal = context.User as RolePrincipal; 
        if (principal != null
        { 
            return context.User.Identity.Name; 
        } 
        else 
        { 
            // We should check the cookies,  
            // because sometimes this method is called in the BeginRequest (before the user is authenticated). 
            HttpCookie cookie = context.Request.Cookies[FormsAuthentication.FormsCookieName]; 
            if (cookie != null
            { 
                FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(cookie.Value); 
                if (ticket != null
                    return ticket.Name; 
            } 
        } 
 
        return string.Empty; 
    } 
 
public class UserUrlMappingInfo : UrlMappingInfo 
    public UserUrlMappingInfo(UrlMappingElement mappingElement) 
        : base(mappingElement) 
    { 
        this.theme = mappingElement.Parameters["theme"]; 
    } 
 
    public string Theme 
    { 
        get { return this.theme; } 
    } 
 
    private string theme; 
 

2. URL mapping configuration:
    <urlMappings type="Custom" customService="UserUrlMappingService, App_Code"
       <add key="user1" value="page1" theme="Levels"/> 
       <add key="user2" value="page2" theme="Orange with left sidebar" /> 
    </urlMappings> 

3. Custom InternalPage:
    - create a CustomInternalPage class in the ~/App_Code/CustomInternalPage.cs
using System; 
using Telerik.Cms.Web; 
 
public class CustomInternalPage : InternalPage 
    protected override void OnPreInit(EventArgs e) 
    { 
        base.OnPreInit(e); 
 
        ICmsUrlContext context = (ICmsUrlContext)this.Context.Items[UrlHelper.CmsPageKey]; 
        if (context != null
        { 
            CmsSiteMapNode node = context.GetSiteMapNode() as CmsSiteMapNode; 
            if (node != null
            { 
                UserUrlMappingInfo urlMappingInfo = node.GetMappingInfo() as UserUrlMappingInfo; 
                if (urlMappingInfo != null
                { 
                    string theme = urlMappingInfo.Theme; 
                    if (!string.IsNullOrEmpty(theme)) 
                    { 
                        this.Theme = theme; 
                    } 
                } 
            } 
        } 
    } 
 
 

    - replace the declaration of InternalPage class with the name of your newly created class in the following file ~/Sitefinity/cmsentrypoint.aspx:
<%@ Page Language="C#" MasterPageFile="~/App_Master/Dummy.master" Inherits="CustomInternalPage" %> 


Finally, the URL Mapping service can be used in many other different custom scenarios.