ASP.NET MVC: Route with optional parameter, but if supplied, must match \d+

前端 未结 6 1319
孤街浪徒
孤街浪徒 2020-11-29 12:00

I\'m trying to write a route with a nullable int in it. It should be possible to go to both /profile/ but also /profile/\\d+.

route         


        
6条回答
  •  天涯浪人
    2020-11-29 12:42

    The simplest way would be to just add another route without the userId parameter, so you have a fallback:

    routes.MapRoute("ProfileDetails", "profile/{userId}",
                    new {controller = "Profile",
                         action = "Details",
                         userId = UrlParameter.Optional},
                    new {userId = @"\d+"});
    
    routes.MapRoute("Profile", "profile",
                    new {controller = "Profile",
                         action = "Details"});
    

    As far as I know, the only other way you can do this would be with a custom constraint. So your route would become:

    routes.MapRoute("ProfileDetails", "profile/{userId}",
                    new {controller = "Profile",
                         action = "Details",
                         userId = UrlParameter.Optional},
                    new {userId = new NullableConstraint());
    

    And the custom constraint code will look like this:

    using System;
    using System.Web;
    using System.Web.Routing;
    using System.Web.Mvc;
    
    namespace YourNamespace
    {
        public class NullableConstraint : IRouteConstraint
        {
            public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
            {
                if (routeDirection == RouteDirection.IncomingRequest && parameterName == "userId")
                {
                    // If the userId param is empty (weird way of checking, I know)
                    if (values["userId"] == UrlParameter.Optional)
                        return true;
    
                    // If the userId param is an int
                    int id;
                    if (Int32.TryParse(values["userId"].ToString(), out id))
                        return true;
                }
    
                return false;
            }
        }
    }
    

    I don't know that NullableConstraint is the best name here, but that's up to you!

提交回复
热议问题