Differentiate Guid and string Parameters in MVC 3

前端 未结 3 1083
清酒与你
清酒与你 2020-12-09 06:38

Using the out-of-the-box method locators in ASP.NET MVC (3 or 4DP), is there a way to have the MVC framework differentiate between a string and Guid without needing to parse

相关标签:
3条回答
  • 2020-12-09 07:17

    First, you must disambigute your methods by giving them two different names:

    public ActionResult DetailsGuid(Guid guid)
    {
        var model = Context.GetData(guid);
        return View(model); 
    }
    
    public ActionResult DetailsString(string id)
    {
        var model = Context.GetData(id);
        return View(model);
    } 
    

    Next, you need a custom route handler to inspect the request, and change the method name accordingly:

    using System.Web.Mvc; 
    using System.Web.Routing; 
    
    public class MyRouteHandler : IRouteHandler 
    { 
        public IHttpHandler GetHttpHandler(RequestContext requestContext) 
        { 
            var routeData = requestContext.RouteData; 
            var stringValue = routeData.Values["id"].ToString();
            Guid guidValue; 
            var action = routeData.Values["action"]; 
            if (Guid.TryParse(stringValue, out guidValue) && (guidValue != Guid.Empty);
                routeData.Values["action"] = action + "Guid"; 
    
            else
                routeData.Values["action"] = action + "String"; 
    
            var handler = new MvcHandler(requestContext); 
            return handler; 
        } 
    } 
    

    Finally, add a Details route at the top of your routes, as follows:

    routes.Add("Details", 
        new Route("{controller}/Details/{id}", 
            new RouteValueDictionary( 
                new { controller = "Home", action = "Details" }), 
                new MyRouteHandler()
            )
        ); 
    );
    

    When a request comes in for details, the Details route will use your custom route handler to inspect the id token. The route handler adds to the action name based on the form of the id token, so that the request will be directed to the appropriate action.

    0 讨论(0)
  • 2020-12-09 07:25

    If you're still registering routes in this way then the GuidRouteConstraint() class was added in a newer version of MVC and should be used instead of a custom implementation:

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            "Guid",
            "{controller}/{action}/{guid}",
            new { controller = "Home", action = "Index" }, 
            new { guid = new GuidRouteConstraint() }
        );
    }
    

    Then you can simply create your action result as:

    public class HomeController : Controller {
        public ActionResult Index(Guid guid) {
        }
    }
    
    0 讨论(0)
  • 2020-12-09 07:29

    My opinion is that using action method selector is more usable and less coding.

    public class GuidMethodSelectorAttribute : ActionMethodSelectorAttribute
    {
        public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
        {
            var idStr = controllerContext.RouteData.Values["id"];
            if (idStr == null)
                return false;
            Guid a;
            var result = Guid.TryParse(idStr.ToString(), out a);
            return result;
        }
    }
    

    This selector inspects request for ID parameter. If it's guid, it returns true. So, to use it:

    public class HomeController : Controller
    {
        [GuidMethodSelector]
        public ActionResult Index(Guid id)
        {
            return View();
        }
        public ActionResult Index(string id)
        {
            return View();
        }
    }
    
    0 讨论(0)
提交回复
热议问题