Skip to content

Commit

Permalink
Fixes #392, URL resolver interop with MvcCodeRouting.
Browse files Browse the repository at this point in the history
  • Loading branch information
NightOwl888 committed Oct 13, 2015
1 parent 599e3db commit f74418e
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Routing;

Expand Down Expand Up @@ -55,5 +56,73 @@ public static string GetAreaName(this RouteData routeData)

return string.Empty;
}

/// <summary>
/// Merges a set of key value pairs with the current DataTokens dictionary. Overwrites any duplicate keys.
/// </summary>
/// <param name="routeData">The route data.</param>
/// <param name="dataTokens">A dictionary of key value pairs to merge.</param>
public static void MergeDataTokens(this RouteData routeData, IDictionary<string, object> dataTokens)
{
if (routeData == null)
return;

foreach (var pair in dataTokens)
{
routeData.DataTokens[pair.Key] = pair.Value;
}
}

/// <summary>
/// Adds the MvcCodeRouting.RouteContext DataToken necessary for interoperability
/// with the MvcCodeRouting library https://github.com/maxtoroq/MvcCodeRouting
/// </summary>
/// <param name="routeData">The route data.</param>
/// <param name="node">The current site map node.</param>
internal static void SetMvcCodeRoutingContext(this RouteData routeData, ISiteMapNode node)
{
if (routeData == null)
return;

var controllerType = node.SiteMap.ResolveControllerType(node.Area, node.Controller);
var mvcCodeRoutingRouteContext = GetMvcCodeRoutingRouteContext(controllerType, node.Controller);
routeData.DataTokens["MvcCodeRouting.RouteContext"] = mvcCodeRoutingRouteContext;
}

private static string GetMvcCodeRoutingRouteContext(Type controllerType, string controllerName)
{
string controllerNamespace = controllerType.Namespace;

int controllersIndex = controllerNamespace.LastIndexOf(".Controllers.");
if (controllersIndex == -1)
{
// this is a top level controller
return string.Empty;
}

// for example if:
// controllerNamespace = "DemoApp.Controllers.Sub1.Sub2.Sub3"

// then selfNamespace is "Sub1.Sub2.Sub3"
string selfNamespace = controllerNamespace.Substring(controllersIndex + 13);

// selfNamespace = parentNamespace + "." + selfNamespaceLast
int parentIndex = selfNamespace.LastIndexOf('.');
string parentNamespace = string.Empty;
string selfNamespaceLast = selfNamespace;

if (parentIndex != -1)
{
// "Sub1.Sub2"
parentNamespace = selfNamespace.Substring(0, parentIndex);
// "Sub3"
selfNamespaceLast = selfNamespace.Substring(parentIndex + 1);
}

// check for default controller
return controllerName.Equals(selfNamespaceLast, StringComparison.Ordinal)
? parentNamespace // default
: selfNamespace; // non-default
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using MvcSiteMapProvider.Web.Mvc;
using MvcSiteMapProvider.Web.Routing;
using System;
using System.Collections.Generic;
using System.IO;
Expand Down Expand Up @@ -123,15 +124,22 @@ protected virtual HttpContextBase CreateHttpContext(ISiteMapNode node, TextWrite

protected virtual RequestContext CreateRequestContext(ISiteMapNode node, TextWriter writer)
{
var realRequestContext = this.mvcContextFactory.CreateRequestContext();

// For interop with MvcCodeRouting, we need to build a data token with the appropriate value.
realRequestContext.RouteData.SetMvcCodeRoutingContext(node);

if (!node.IncludeAmbientValuesInUrl)
{
var httpContext = this.CreateHttpContext(node, writer);
return this.mvcContextFactory.CreateRequestContext(httpContext);
}
else
{
return this.mvcContextFactory.CreateRequestContext();
var fakeRequestContext = this.mvcContextFactory.CreateRequestContext(httpContext);
fakeRequestContext.RouteData.MergeDataTokens(realRequestContext.RouteData.DataTokens);
fakeRequestContext.RouteData.Route = realRequestContext.RouteData.Route;
fakeRequestContext.RouteData.RouteHandler = realRequestContext.RouteData.RouteHandler;
return fakeRequestContext;
}

return realRequestContext;
}
}
}

0 comments on commit f74418e

Please sign in to comment.