Skip to content

Instantly share code, notes, and snippets.

@robgha01
Created January 14, 2017 13:12
Show Gist options
  • Save robgha01/34ce1e075f7e34ea2cb4e26029d4cdec to your computer and use it in GitHub Desktop.
Save robgha01/34ce1e075f7e34ea2cb4e26029d4cdec to your computer and use it in GitHub Desktop.
Umbraco 7 Custom route with UmbracoVirtualNodeRouteHandler
public class DocumentTypeRouteConstraint : IRouteConstraint
{
private readonly MatchFunc match;
public DocumentTypeRouteConstraint(string documentTypeAlias, MatchFunc match = null)
{
this.match = match;
DocumentTypeAlias = documentTypeAlias;
}
public delegate bool MatchFunc(
HttpContextBase httpContext,
Route route,
string parameterName,
RouteValueDictionary values,
RouteDirection routeDirection);
public string DocumentTypeAlias { get; }
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
var controller = values["controller"]?.ToString() ?? string.Empty;
if (controller.Equals(DocumentTypeAlias) && match != null && match(httpContext, route, parameterName, values, routeDirection))
{
return true;
}
return false;
}
}
public class DocumentTypeUrlNodeRouteHandler : UmbracoVirtualNodeRouteHandler
{
public DocumentTypeUrlNodeRouteHandler(string documentTypeAlias)
{
DocumentTypeAlias = documentTypeAlias;
}
public string DocumentTypeAlias { get; }
protected override IPublishedContent FindContent(RequestContext requestContext, UmbracoContext umbracoContext)
{
try
{
if (requestContext != null && requestContext.HttpContext.Request.Url != null)
{
var path = requestContext.HttpContext.Request.Url.GetAbsolutePathDecoded();
var parts = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
var tmpUrl = "/";
// Lets try to get the content by using parts of the url until we find it.
for (var index = 0; index < parts.Length; index++)
{
tmpUrl += parts[index] + "/";
try
{
// Try to resolve it as a route.
var content = UmbracoContext.Current.ContentCache.GetByRoute(tmpUrl);
if (content.DocumentTypeAlias.Equals(DocumentTypeAlias))
{
return content;
}
}
catch (Exception ex)
{
// ignored
}
}
var rootNodes = umbracoContext.ContentCache.GetAtRoot();
var profilePage = rootNodes.DescendantsOrSelf(DocumentTypeAlias).FirstOrDefault(x => x.UrlName == parts.First());
if (profilePage != null)
{
return profilePage;
}
}
}
catch (Exception ex)
{
// ignored
}
return null;
}
}
@inherits UmbracoViewPage<ProfilePageModel>
<p>Profile user is <b>@ViewContext.RouteData.Values["alias"]</b></p>
public class ProfilePageModelController : UCodeFirstController
{
public override ActionResult Index(RenderModel model)
{
try
{
var m = model.Content.ToStrongContent<ProfilePageModel>();
// Get the actuall alias (extra route value added)
var alias = RouteData.Values["alias"];
return View(model.Content.GetTemplateAlias(), m);
}
catch (InvalidOperationException)
{
// Exception, return base RenderModel
return View(model.Content.GetTemplateAlias(), model);
}
}
}
public sealed class RouteBootstraper : ApplicationBootstrapBase
{
protected override void ApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
// Route profile page // ToDo: Move this to BlueLeet.UWeb
RouteTable.Routes.MapUmbracoRoute(
"Profile",
"{action}/{alias}",
new { Controller = nameof(ProfilePageModel), Action = nameof(ProfilePageModel) },
new DocumentTypeUrlNodeRouteHandler(nameof(ProfilePageModel)),
new { Alias = new DocumentTypeRouteConstraint(nameof(ProfilePageModel), MatchProfilePage) });
}
private bool MatchProfilePage(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
var alias = values["alias"]?.ToString() ?? string.Empty;
return !string.IsNullOrEmpty(alias);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment