Support URL generation without RequestContext and/or RouteContext #1157

Imported from the CodePlex archive for reference purposes. Support for MvcCodeRouting has ended.

Reported on

Using MvcCodeRouting with the default setup will correctly generate routes and @Html.ActionLink etc all generate the correct Url.

However if you are using another tool to generate the Urls such as MvcSiteMap (https://github.com/maartenba/MvcSiteMapProvider) or MvcRouteTester (https://github.com/AnthonySteele/MvcRouteTester) then it is generating null routes.

This seems to be a breaking change between version 1.0.0 and 1.0.1 - when stepping through the source it seems to ultimately be in ICodeRoute.cs approx line 112

 if (requestRouteDataTokens.ContainsKey(DataTokenKeys.RouteContext))
        routeContext = (string)requestRouteDataTokens[DataTokenKeys.RouteContext];

     if (routeContext == null)
        return null;

as routeContext is seemingly coming back as null when called from these other tools.

Commented on link

First of all, it is unfortunate that a patch release contains a breaking change, sorry about that. Even though v1.0.1 didn’t introduce new features, I did a lot of refactoring in preparation for Web API support. I should have just named it v1.1

About the issue, MvcCodeRouting will generate URLs if the route of the current request was also created by MvcCodeRouting, this is to determine the route context relationship between the current route and the tested route.

MvcCodeRouting currently requires a RequestContext to generate URLs. This is not the case for standard routing, where you can do this:

RouteTable.Routes.GetVirtualPath(null /* requestContext */, new RouteValueDictionary(new { controller = "Home", action = "Index" })).VirtualPath

I don’t know how MvcSiteMapProvider and MvcRouteTester are implemented, but if they don’t use routing while generating URLs, you can workaround with something like this:

RouteTable.Routes.GetVirtualPath(new RequestContext(Context/* current HttpContext */, new RouteData { DataTokens = { { "MvcCodeRouting.RouteContext", "" } } }), new RouteValueDictionary(new { controller = "Home", action = "Index" })).VirtualPath

If they do use routing, then you can add "MvcCodeRouting.RouteContext", "" to the DataTokens of their routes.

I hope this all makes sense, don’t hesitate to ask more questions if you don’t understand. I am willing to improve support for this use case if we can come up with a well justified and robust feature specification.

Commented on link

Hello.

May be this demo project will help with MvcSiteMapNodeProvider?