Reputation:
I have two routes in my asp.net mvc app
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{culture}/{controller}/{action}/{id}",
defaults: new { culture = CultureHelper.GetDefaultCulture(), controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default no language",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
When i enter url http://localhost/gallery
in browser, i'm redirected to http://localhost/
, when i try http://localhost/gallery/index
, i'm geting 404 error
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /gallery/index
when i add any implemented language to url (http://localhost/en/gallery
), app is working.
I'm new to routes and webapp programing, so i would appriciate if anyone could help me with this with detailed explanation how to fix this.
Upvotes: 1
Views: 322
Reputation: 23690
The problem is that you have two routes, but the first route will always bind because it can't tell the difference between {culture}/{controller}/{action}/{id}
and {controller}/{action}/{id}
when binding /gallery
- is it a culture or just a controller name?
There's no way to tell without checking, it will just bind the first match.
If you remove the default values then it might work, but you will always have to specify the action and controller:
routes.MapRoute(
name: "Default",
url: "{culture}/{controller}/{action}/{id}",
defaults: new { culture = CultureHelper.GetDefaultCulture(),
/* controller = "Home", action = "Index",*/ id = UrlParameter.Optional }
);
{culture}/{controller}/{action}/{id}
will now bind:
and {controller}/{action}/{id}
will bind:
Your other option is to create a custom route constraint to validate that the first value is a valid culture value:
public class IsValidCultureConstraint : IRouteConstraint
{
public bool Match
(
HttpContextBase httpContext,
Route route,
string parameterName,
RouteValueDictionary values,
RouteDirection routeDirection
)
{
if (string.IsNullOrWhiteSpace(values["culture"]))
{
return this.IsValidCulture();
}
return false;
}
private bool IsValidCulture(string cultureString)
{
//
// Logic here to check valid culture(s)
//
// Example
if (String.Equals(cultureString.Trim(), "en",
StringComparison.OrdinalIgnoreCase))
{
// English is valid
return true;
}
return false;
}
}
routes.MapRoute(
name: "Default",
url: "{culture}/{controller}/{action}/{id}",
defaults: new { culture = CultureHelper.GetDefaultCulture(),
id = UrlParameter.Optional,
constraints: new { culture = new IsValidCultureConstraint() }
});
With that in place, it will only ever match the first route if the value entered into the URL is a valid culture. Of course, you will need to provide the logic to perform the check properly.
Upvotes: 1