Francis Gilbert
Francis Gilbert

Reputation: 3442

Sitecore MVC routing to resolve a hyphenated name

I am trying to get Sitecore MVC routing to give me content from the path of

/Home/Test Url/With Space

from the URL:

/test-url/with-space

So I need Sitecore to be able to recognise the URL has a hyphen, but can still resolve to the path without a hyphen.

Here is what I have so far:

routes.MapRoute(
   name: "Hyphenated URL",
   url: "test-url/{valuename}",
   defaults: new { scItemPath = "/Home/Test Url/{valuename}" });

This works with a path of:

/test-url/with space

but if I add the hyphen in between "with" and "space", I can't get it to resolve. I'm guessing I need a custom route processor. Any ideas? Thanks in advance.

Upvotes: 0

Views: 763

Answers (2)

Brian R. Mullin
Brian R. Mullin

Reputation: 423

You could create a custom route.

routes.MapHyphenatedRoute(
    name: "Hyphenated URL",
    url: "{controller}/{action}",
    defaults: new { scItemPath = "/Home/{controller}/{action}" }
    );

The idea here is to intercept route values with hyphens and translate them to your desired format. URLs without hyphens would remain untouched. Sitecore would still need the ability to handle the scItemPath.

public static class RouteCollectionExtensions
{
    public static Route MapHyphenatedRoute(this RouteCollection routes, string name, string url, object defaults)
    {
        var route = new HyphenatedRoute(url, defaults);
        routes.Add(name, route);
        return route;
    }
}

public class HyphenatedRoute : Route
{
    public HyphenatedRoute(string url, object defaults) :
        base(url, new RouteValueDictionary(defaults), new MvcRouteHandler())
    { }

    public override RouteData GetRouteData(System.Web.HttpContextBase httpContext)
    {
        var routeData = base.GetRouteData(httpContext);

        if (routeData != null)
        {
            RouteValueDictionary values = routeData.Values;
            values["controller"] = Dehyphenate(values["controller"] as string);
            values["action"] = Dehyphenate(values["action"] as string);
        }

        return routeData;
    }

    public override VirtualPathData GetVirtualPath(RequestContext ctx, RouteValueDictionary values)
    {
        values["controller"] = Hyphenate((values["controller"] as string));
        values["action"] = Hyphenate(values["action"] as string);
        return base.GetVirtualPath(ctx, values);
    }

    private static string Hyphenate(string value)
    {
        if (!string.IsNullOrEmpty(value) && value.IndexOf(' ') >= 0)
        {
            return System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToLower(value.Replace(' ', '-'));
        }

        return value;
    }

    private static string Dehyphenate(string value)
    {
        if (!string.IsNullOrEmpty(value) && value.IndexOf('-') >= 0)
        {
            return System.Globalization.CultureInfo.CurrentCulture.TextInfo.ToTitleCase(value.Replace('-', ' '));
        }

        return value;
    }
}

Your scenario may need different handling, but this code might help if you need route translation.

Upvotes: 1

computerjules
computerjules

Reputation: 316

Sitecore 7 handles this out of the box, but in Sitecore 6.x you will need to add the following to the <encodeNameReplacements> element in your web.config:

<replace mode="on" find=" " replaceWith="-" />

This will basically tell Sitecore to map hyphens in the URL to spaces in the item's name.

Upvotes: 0

Related Questions