Reputation: 210
When I'm trying to add constraint to default route as follows
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { id = @"\d+" }
);
}
and running the site, I'm getting:
HTTP Error 403.14 - Forbidden error
The Web server is configured to not list the contents of this directory.
Just this single line with constraint causes the issue. When it's commented the site is running as expected. I'm even able to reproduce this locally on newly created MVC project.
Is this some sort of bug, or don't I understand something crucial about route constraints?
I'm using .NET 4.5.2, MVC 5.2.3, VS 2015 with IIS Express 10.0.
Upvotes: 0
Views: 1620
Reputation: 12491
Ok i suppose your problem and solutions for it you can find here.
Solution adapted to your situation:
public class NullableConstraint : IRouteConstraint
{
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
{
if (routeDirection == RouteDirection.IncomingRequest && parameterName == "id")
{
// If the userId param is empty (weird way of checking, I know)
if (values["id"] == UrlParameter.Optional)
return true;
// If the userId param is an int
int id;
if (Int32.TryParse(values["id"].ToString(), out id))
return true;
}
return false;
}
}
And your Route:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
constraints: new { id = new NullableConstraint() }
);
Upvotes: 1
Reputation: 846
Haven't tried this ,You might want to define two routes to achieve what you need
routes.MapRoute(
name: "Default1",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index"},
constraints: new {id=@"\d+"}
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index",id= UrlParameter.Optional }
);
If id is null it falls back to the default route.
Upvotes: 0