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

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

问题描述

我试着做一个路由,这样我可以显示用户名在这样的网址:

的http:// localhost1234 /约翰

这是我routeconfig:

  routes.MapRoute(
                名称:用户,//路线名称
                网址:{用户名},// URL带参数
                默认:新{控制器=家,行动=指数,用户名=} //参数默认
            );            routes.MapRoute(
                名称:默认,
                网址:{控制器} / {行动} / {ID}
                默认:新{控制器=家,行动=索引,ID = UrlParameter.Optional}
            );

这是我的HomeController:

 公众的ActionResult指数(字符串的用户名=测试)
 {
   返回查看();
  }

首先,该URL不会改变。当我设置 =用户名测试我的路由的配置里面,URL不会改变。

其次,我无法浏览到我的其他控制器。如果我更改URL,以的http:// localhost123 /欢迎,没有任何反应。它应该我重定向到一个新的一页。

我在做什么错在这里?

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

我用Google搜索,所有关于这个问题的答案,说我应该使用路由像上面的。


解决方案

在其自己的,你的路由并不会因为工作,如果URL是 ... /产品意义你想要导航到 ProductController的指数()方法,将匹配您的第一个路线(并假设产品是用户名。你需要一个路由约束添加到您的肉鹅定义返回真正如果用户名是有效的,

假设你有一个 UserController的通过以下方法

  //匹配的http://..../Bryan
公众的ActionResult指数(用户名字符串)
{
    //显示主页用户
}//匹配HTTP://..../Bryan/Photos
公众的ActionResult照片(字符串的用户名)
{
    //显示用户照片
}

然后你的路由定义需要

 公共类RouteConfig
{
    公共静态无效的RegisterRoutes(RouteCollection路线)
    {
        routes.IgnoreRoute({}资源个.axd / {*} PATHINFO);
        routes.MapRoute(
            名称:用户,
            网址:{用户名},
            默认:新{控制器=用户,行动=索引},
            限制:新{用户名=新UserNameConstraint()}
        );
        routes.MapRoute(
            名称:UserPhotos
            网址:{用户名} /照片,
            默认:新{控制器=用户,行动=照片},
            限制:新{用户名=新UserNameConstraint()}
        );
        routes.MapRoute(
            名称:默认,
            网址:{控制器} / {行动} / {ID}
            默认:新{控制器=测试,行动=索引,ID = UrlParameter.Optional}
        );
    }    公共类UserNameConstraint:IRouteConstraint
    {
        公共BOOL匹配(HttpContextBase HttpContext的,路由路径,字符串参数名称,RouteValueDictionary价值,RouteDirection routeDirection)
        {
            清单<串GT;用户=新的List<串GT;(){布莱恩,泉};
            //从URL中的用户名
            。VAR用户名=值[用户名]的ToString()ToLower将()。
            //检查匹配(假定不区分大小写)
            返回users.Any(X => x.ToLower()==用户名);
        }
    }
}

如果URL是 ... /布赖恩,它会匹配用户的路线,你将执行指数() UserController的方法(和值用户名布莱恩

如果URL是 ... /泉/照片,它会匹配 UserPhotos 路线,你会执行照片() UserController的方法(和值用户名

如果URL是 ... /产品/细节/ 4 ,那么路由约束将返回false前2路由定义,你将执行详情() ProductController的

如果URL是 ... /彼得 ... /彼得/照片并没有与 =用户名彼得那么它将返回 404未找​​到

用户

请注意,该样品code以上的硬codeS的用户,但在现实中,你会调用返回一个包含有效的用户名集合的服务。为了避免撞上数据库的每个请求,你应该考虑使用的MemoryCache 缓存集合。在code会首先检查它是否存在,如果不填充它,然后检查如果集合包含用户名。您还需要确保,如果添加一个新用户的高速缓存无效。

Im trying to make a route so I can show the username In the URL like this:

http://localhost1234/john

Here Is my 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 }
            );

Here Is my HomeController:

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

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

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.

What am I doing wrong here?

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.

解决方案

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).

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
}

Then you route definitions need to be

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

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")

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")

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

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

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天全站免登陆