【问题标题】:MVC 4, MapRoute for /{parameter} URLMVC 4,/{parameter} URL 的 MapRoute
【发布时间】:2014-06-04 16:07:38
【问题描述】:

如何以这种格式映射 URL

http://DOMAIN/{userID}

但不覆盖默认格式 {controller}/{action}/{id}??

我试过了,但它不起作用:

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

routes.MapRoute("Users", "{userID}", new { controller = "Users", action = "GetUser" });

【问题讨论】:

  • 只需切换 2 行(将用户路由移至顶部)即可。请记住,它会将所有像 /home 这样的 url 捕获到用户控制器而不是 Home 控制器中。如果您不喜欢这种情况发生,您将需要一个正则表达式作为 UserId 的约束

标签: asp.net-mvc asp.net-mvc-4 maproute


【解决方案1】:

在默认路由之前插入这个

routes.MapRoute("Users", "{userID}", new { controller = "Users", action = "GetUser", userID=UrlParameter.Optional });

那么 GetUser 方法必须有一个名为 userID 的参数,以便路由处理程序能够正确路由。

更新:

public class UsernameUrlConstraint : IRouteConstraint
{

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values,
                      RouteDirection routeDirection)
    {
        if (values[parameterName] != null)
        {
          // check if user exists in DB
          // if it does, return true
        }
        return false;
    }
}

在你的路线中:

routes.MapRoute("Users",
                "{userID}", 
                new { controller = "Users", action = "GetUser" },
                new {IsUser=new UsernameUrlConstraint()}
                );

请注意,这每次都会命中数据库,因此在您存储用户名及其是否存在的地方实现一些内存缓存(memcached 或 .net 内存缓存)可能是个好主意,这样您不仅会阻止存在的用户的 db 命中,还会阻止不存在的用户的 db 命中。例如,如果有人决定访问用户 X 1000 次,这样您将只使用缓存版本而不是进行 1000 次数据库调用。

【讨论】:

  • 在这种情况下,例如 /Home 正在路由到 /Users/GetUser... 任何方法首先检查 {userID} 是否是控制器,如果不是,则转到 /Users/GetUser/{userID }?
  • 我喜欢这个解决方案!!非常感谢!!
【解决方案2】:

您确实不能根据您提供的信息。如果用户 ID 是您可以使用正则表达式匹配的特定格式,您也许可以使用路由过滤器参数并按此过滤。该路由也需要列在默认路由上方。

routes.MapRoute(
    name: "Users",
    url: "{userID}",
    defaults: new
    {
        controller = "Users",
        action = "GetUser",
    }, 
    new {postId = @"[\w]{3,7}" }
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

但是,由于 \w 是任何单词字符,它仍然会匹配任何介于 3 到 7 个字符之间的控制器名称。如果您可以使用更具体的正则表达式,则可以完成。

【讨论】:

  • {UserID} 的正则表达式是 [\w]{3,7}... 但是如果我在默认路由之上的那个路由例如 /Home/Index 它不起作用:S
  • 因为 \w 是任何单词字符,它仍然会匹配任何介于 3 到 7 个字符之间的控制器名称。如果您可以使用更具体的正则表达式,则可以完成。
  • 我编辑了我的答案以包含您的正则表达式,但它仍然带有上面评论中的警告。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-24
  • 2015-04-24
  • 1970-01-01
  • 1970-01-01
  • 2015-10-14
相关资源
最近更新 更多