Reputation: 1144
I have a problem with back linking from area view to non area view.
Web application tree:
Default route config:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute(
name: "Localization",
url: "{culture}/{controller}/{action}/{id}",
defaults: new { culture = "de-DE", area = "", controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { area = "", controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
Area route config:
public class Area1AreaRegistration : AreaRegistration
{
public override string AreaName
{
get
{
return "Area1";
}
}
public override void RegisterArea(AreaRegistrationContext context)
{
context.MapRoute(
"Photovoltaics_localized",
"{culture}/Photovoltaics/{controller}/{action}/{id}",
new { culture = "de-DE", action = "Index", id = UrlParameter.Optional }
);
context.MapRoute(
"Area1_default",
"Area1/{controller}/{action}/{id}",
new { action = "Index", id = UrlParameter.Optional }
);
}
}
Register route configs (Global.asax.cs)
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
[..]
When I'm inside a base view (/Views/Base/Index.cshtml) the code @Html.ActionLink("My home link", "Index", "Home")
generates the link I expected http://localhost:81/de-DE/Home .
When I'm inside a area view (/Areas/Area1/Views/Setting/Index.cshtml) the same code generates a link http://localhost:81/de-DE/Area1/Home but this points to nowhere.
I learned that the code @Html.ActionLink("My home link", "Index", "Home", new { area = ""}, null)
works in both, area and non area views and leads to the correct http://localhost:81/de-DE/Home view.
How can I structur my route configs in a way that calling a link creation methode with no area as parameter always links to the base views/controllers?
Or is there a better solution to achieve this?
What I expect is:
@Html.ActionLink("My home link", *action*, "controller")
= http://localhost:81/de-DE/action
@Html.ActionLink("My home link", *action*, *controller*, new { area = *area*}, null)
= http://localhost:81/de-DE/area/action
Upvotes: 0
Views: 227
Reputation: 352
This has nothing to do with routing. This is the default behaivor for the ActionLink method URL creation. You can see this on the following code (taken from the ASP.NET MVC codeset):
if (values != null)
{
object targetAreaRawValue;
if (values.TryGetValue("area", out targetAreaRawValue))
{
targetArea = targetAreaRawValue as string;
}
else
{
// set target area to current area
if (requestContext != null)
{
targetArea = AreaHelpers.GetAreaName(requestContext.RouteData);
}
}
}
As you can see if you don't pass a value for area, it will take the current area you are in.
The only solution I can think of, would be to create your own HTML extension. Something similar to this:
public static MvcHtmlString ActionLink(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName)
{
return htmlHelper.ActionLink(linkText, actionName, controllerName, new { area = String.Empty });
}
Upvotes: 1