drty
drty

Reputation: 210

ASP.NET MVC: Default route with id constraint

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

Answers (2)

teo van kot
teo van kot

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

curiousgeek
curiousgeek

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

Related Questions