I have an MVC 4
application. In that application I have certain Areas, whose URL is not resolved properly. The LocationAreaRegistration.cs
is as follows:
context.MapRoute(
"Location_default",
"{culture}/{controller}/{action}/{id}",
new { culture = "en", action = "LocationIndex", id = UrlParameter.Optional },
new { controller = "(LocationIndex)" }
);
My route.config
is as follows:
routes.MapRoute(
name: "Default",
url: "{culture}/{controller}/{action}/{id}",
defaults: new { culture = "en", controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "Locator.Areas.Location.Controllers" }
).DataTokens.Add("area", "Location");
I have also tried to change the route.config
as below:
routes.MapRoute(
name: "Default",
url: "{culture}/{controller}/{action}/{id}",
defaults: new { culture = "en", controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new[] { "Locator.Areas.Location.Controllers" }
);
None of the approaches worked and I get The resource cannot be found
error.
However when I change the LocationAreaRegistration.cs
as follows, it works:
context.MapRoute(
"Location_default",
"{culture}/Location/{controller}/{action}/{id}",
new { culture = "en", action = "LocationIndex", id = UrlParameter.Optional },
new { controller = "(LocationIndex)" }
);
But I do not want the URL to contain the Location
(Area name). What am I doing wrong?
EDIT
The URLs that I would be going to will be somewhat like:
http://localhost/en/LocationIndex/LocationIndex
Here en
is the current culture, Home
is the controller
name and Index
is the action method
name.
To make the Location
area the default set of routes for your MVC application, you just need to define your RouteConfig.cs
as follows:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default_Localized",
url: "{culture}/{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { culture = new CultureConstraint(defaultCulture: "en", pattern: "[a-z]{2}") },
namespaces: new string[] { "Locator.Areas.Location.Controllers" }
).DataTokens["area"] = "Location";
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { culture = "en", controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "Locator.Areas.Location.Controllers" }
).DataTokens["area"] = "Location";
}
}
Note that this will completely replace any functionality of your default controllers in the application and send all of the requests to the Location
namespace.
You should not put any route definitions into your LocationAreaRegistration.cs
file. This will ensure they are run last and don't screw with any of your other area routes.
Here is the definition of CultureConstraint
. See this answer for more details about how to localize your routes.
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Routing;
public class CultureConstraint : IRouteConstraint
{
private readonly string defaultCulture;
private readonly string pattern;
public CultureConstraint(string defaultCulture, string pattern)
{
this.defaultCulture = defaultCulture;
this.pattern = pattern;
}
public bool Match(
HttpContextBase httpContext,
Route route,
string parameterName,
RouteValueDictionary values,
RouteDirection routeDirection)
{
if (routeDirection == RouteDirection.UrlGeneration &&
this.defaultCulture.Equals(values[parameterName]))
{
return false;
}
else
{
return Regex.IsMatch((string)values[parameterName], "^" + pattern + "$");
}
}
}