I have an application here with a mix of webform and mvc. I specify the routing as below
routes.Add("AspxRoute", new Route("Upload/New", new WebFormRouteHandler<Page>("~/Uploads.aspx")));
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = "" } // Parameter defaults
);
So that virtual path to "Upload/New" actually maps to an aspx webform page.
But my problem is that Html.ActionLink("Test", "Controller", "Action") now renders
/Upload/New?Controller=Controller&Action=Action
Having looked at the MVC source code, I understand that it is because ActionLink calls to RouteCollection.GetVirtualPath(requestContext, routeName, mergedRouteValues), where routeName is left to null. And somehow this defaults to use the AspxRoute route to construct the url. I tried to added another route before "AspxRoute", but it seems it always defaults to the non-mvc routehandler one.
How does RouteCollection.GetVirtualPath behave when routeName is null? And why is it behaving this way for my case?
How do I construct a correct url? Do I need to write a new Htmlhelper extension?
Cheers
Yes, there is a difference. Html. ActionLink generates an <a href=".."></a> tag whereas Url. Action returns only an url.
Html. ActionLink creates a hyperlink on a view page and the user clicks it to navigate to a new URL. It does not link to a view directly, rather it links to a controller's action.
You can set up a default route: routes. MapRoute( "Default", // Route name "", // URL with parameters new { controller = "Home", action = "Index"} // Parameter defaults ); Just change the Controller/Action names to your desired default.
Yes, We can use multiple URLs to the same action with the use of a routing table. foreach(string url in urls)routes. MapRoute("RouteName-" + url, url, new { controller = "Page", action = "Index" });
An alternative option would be to add a custom constraint to your WebFormRoute(s). For example, you could create an implementation of IRouteConstraint to match RouteDirection.IncomingRequest, then use it to ensure the route is ignored by Server-Generated routes (such as ActionLink) but still used by client-generated requests. Something like:
public class IncomingOnlyRouteConstraint: IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if (routeDirection == RouteDirection.IncomingRequest)
{
return true;
}
return false;
}
}
And then add the constraint to your route:
routes.Add("AspxRoute", new Route("Upload/New", null,
new RouteValueDictionary() { {"WebFormsConstraint", new IncomingOnlyRouteConstraint()} },
new WebFormRouteHandler<Page>("~/Uploads.aspx")));
Of course you may prefer to add your own style of constraint, this one is quite limiting on the route that implements it, but it's just an example of one way you could resolve the issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With