ASP.NET MVC 中的路由,在 URL 中显示用户名 [英] Routing in ASP.NET MVC, showing username in URL

查看:25
本文介绍了ASP.NET MVC 中的路由,在 URL 中显示用户名的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个路由,以便我可以在 URL 中显示用户名,如下所示:

I'm trying to make a route so I can show the username in the URL like this:

http://localhost1234/john

这是我的路由配置:

 routes.MapRoute(
                name: "users", // Route name
                url: "{username}", // URL with parameters
                defaults: new { controller = "Home", action = "Index", username = "" } // Parameter defaults
            );

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

这是我的 HomeController:

Here is my HomeController:

 public ActionResult Index(string username = "Test")
 {
   return View();
  }

首先,URL 没有改变.当我在路由配置中设置 username = "Test" 时,URL 不会改变.

First of all, the URL Is not changed. When I set username = "Test" inside my route-config, the URL is not changed.

其次,我无法导航到其他控制器.如果我将 URL 更改为 http://localhost123/Welcome,则没有任何反应.它应该将我重定向到一个新页面.

Second, I can't navigate to my other controllers. If I change the URL to http://localhost123/Welcome, nothing happens. It should redirect me to a new page.

我在这里做错了什么?

如果我改变路由的顺序,我可以导航到其他页面,但URL中不显示用户名.

If I change the order of the routes, I can navigate to other pages, but the username Is not displayed In the URL.

我用谷歌搜索过,关于这个主题的所有答案都说我应该使用像上面那样的路线.

I have googled and all of the answers on this subject says that I should use a route like the one above.

推荐答案

就其本身而言,您的路由将不起作用,因为如果 url 是 .../Product 意味着您想要导航到Index()ProductController 方法,它会匹配你的第一个路由(并假设Product"是 username.你需要添加一个如果 username 有效,则返回 true 的 roue 定义的路由约束,否则返回 false(在这种情况下,它将尝试以下路由到找到匹配项).

On its own, your routing will not work because if the url was .../Product meaning that you wanted to navigate to the Index() method of ProductController, it would match your first route (and assume "Product" is the username. You need to add a route constraint to your roue definitions that returns true if the username is valid and false if not (in which case it will try the following routes to find a match).

假设您有一个具有以下方法的 UserController

Assuming you have a UserController with the following methods

// match http://..../Bryan
public ActionResult Index(string username)
{
    // displays the home page for a user
}

// match http://..../Bryan/Photos
public ActionResult Photos(string username)
{
    // displays a users photos
}

那么你的路由定义需要

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.MapRoute(
            name: "User",
            url: "{username}",
            defaults: new { controller = "User", action = "Index" },
            constraints: new { username = new UserNameConstraint() }
        );
        routes.MapRoute(
            name: "UserPhotos",
            url: "{username}/Photos",
            defaults: new { controller = "User", action = "Photos" },
            constraints: new { username = new UserNameConstraint() }
        );
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Test", action = "Index", id = UrlParameter.Optional }
        );
    }

    public class UserNameConstraint : IRouteConstraint
    {
        public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
        {
            List<string> users = new List<string>() { "Bryan", "Stephen" };
            // Get the username from the url
            var username = values["username"].ToString().ToLower();
            // Check for a match (assumes case insensitive)
            return users.Any(x => x.ToLower() == username);
        }
    }
}

如果 url 是 .../Bryan,它将匹配 User 路由,你将在UserController(username 的值为 "Bryan")

If the url is .../Bryan, it will match the User route and you will execute the Index() method in UserController (and the value of username will be "Bryan")

如果 url 是 .../Stephen/Photos,它将匹配 UserPhotos 路由,您将执行 Photos()UserController 中的方法(username 的值将是 "Stephen")

If the url is .../Stephen/Photos, it will match the UserPhotos route and you will execute the Photos() method in UserController (and the value of username will be "Stephen")

如果 url 是 .../Product/Details/4,那么路由约束将为前 2 个路由定义返回 false,您将执行 Details()ProductController

If the url is .../Product/Details/4, then the route constraint will return false for the first 2 route definitions and you will execute the Details() method of ProductController

如果 url 是 .../Peter.../Peter/Photos 并且没有用户 username = "Peter" 然后它会返回 404 Not Found

If the url is .../Peter or .../Peter/Photos and there is no user with username = "Peter" then it will return 404 Not Found

请注意,上面的示例代码对用户进行了硬编码,但实际上您将调用一个服务,该服务返回一个包含有效用户名的集合.为了避免每次请求都访问数据库,您应该考虑使用 MemoryCache 来缓存集合.代码首先检查它是否存在,如果不存在,则检查集合是否包含username.如果添加了新用户,您还需要确保缓存失效.

Note that the the sample code above hard codes the users, but in reality you will call a service that returns a collection containing the valid user names. To avoid hitting the database each request, you should consider using MemoryCache to cache the collection. The code would first check if it exists, and if not populate it, then check if the collection contains the username. You would also need to ensure that the cache was invalidated if a new user was added.

这篇关于ASP.NET MVC 中的路由,在 URL 中显示用户名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆