ASP.NET MVC中的路由,显示URL中的用户名

时间:2016-05-21 02:55:47

标签: c# asp.net-mvc routes

我试图制作一条路线,这样我就可以在网址中显示用户名:

http://localhost1234/john

这是我的routeconfig:

 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:

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

首先,URL未更改。当我在route-config中设置username = "Test"时,URL不会更改。

其次,我无法导航到我的其他控制器。如果我将网址更改为http://localhost123/Welcome,则不会发生任何事情。它应该将我重定向到新页面。

我在这里做错了什么?

如果我更改路线的顺序,我可以导航到其他页面,但用户名不显示在URL中。

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

2 个答案:

答案 0 :(得分:9)

如果网址为.../Product意味着您要导航到Index() ProductController方法,那么您的路由就不会有效,因为它会匹配您的第一条路线(并假设" Product"是username。如果true有效且username,则需要向路由约束添加路由约束,返回false。如果不是(在这种情况下,它将尝试以下路由来查找匹配)。

假设您有UserController以下方法

// 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);
        }
    }
}

如果网址为.../Bryan,则会与User路由匹配,您将在Index()中执行UserController方法(以及username的值将是"Bryan"

如果网址为.../Stephen/Photos,则会与UserPhotos路由匹配,您将在Photos()中执行UserController方法(以及username的值将是"Stephen"

如果网址为.../Product/Details/4,则前2个路由定义的路由约束将返回false,您将执行Details()的{​​{1}}方法

如果网址为ProductController.../Peter且没有.../Peter/Photos用户,则会返回username = "Peter"

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

答案 1 :(得分:0)

您需要为网站的不同部分对网址进行分类,以便网址模式匹配机制顺利进行。例如,在您的情况下,放置一个类别&#39; profile&#39;或其他任何东西。现在您的请求网址看起来像http://localhost1234/profile/john,路由将是

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

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

有关详细信息,请访问链接Routing in MVC