Filter for redirecting default item routes to firendly URLs

Topics: General, Writing modules
Developer
Nov 19, 2013 at 10:15 PM
The below filter will redirect any requests for /Contents/Item/Display/ID to the item's friendly URL (e.g. coming from AutoroutePart) if that exists, e.g. /my-item. More technically: if one fetches an item through the default ItemController from under a different URL than the one with the highest priority then this will redirect to the URL with the highest priority.

Created by Lombiq.
    public class RedirectFilter : FilterProvider, IActionFilter
    {
        private readonly IContentManager _contentManager;


        public RedirectFilter(IContentManager contentManager)
        {
            _contentManager = contentManager;
        }
    
            
        public void OnActionExecuted(ActionExecutedContext filterContext)
        {
        }

        public void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var routeValues = filterContext.RouteData.Values;
            int id;
            if (routeValues["area"].ToString() != "Contents" ||
                routeValues["controller"].ToString() != "Item" ||
                routeValues["action"].ToString() != "Display" ||
                routeValues["id"] == null ||
                !int.TryParse(routeValues["id"].ToString(), out id))
            {
                return;
            }

            var item = _contentManager.Get(id);

            if (item == null) return;

            var displayUrl = new UrlHelper(filterContext.RequestContext).RouteUrl(_contentManager.GetItemMetadata(item).DisplayRouteValues);

            if (!filterContext.HttpContext.Request.Url.LocalPath.StartsWith(displayUrl))
            {
                filterContext.Result = new RedirectResult(displayUrl, true);
            }
        }
    }