在 ASP.NET MVC 中动态生成许多路由...这是一个完全坏主意吗?
这是我的困境。我有一个实体集合,我想用它们来定义作为一组路线的起点。例如,我想为站点中的所有用户提供其自己的“子站点”(格式为 mydomain.com/username),然后将所有 UserController 操作挂在其上。
这是我正在做的事情的一个粗略示例:
我有一个“UserController”,具有“Index”、“Profile”和“Bio”等操作方法。
public ActionResult Profile( int UserID )
{
User u = User.SingleOrDefault(u => u.UserID == UserID);
return View(u);
}
在 RegisterRoutes() 方法中,我这样做:
foreach (User user in User.Find(u => u.Active == true))
{
routes.MapRoute(
"",
user.UserName + "/{action}",
new { controller="User", action="Index", UserID=user.UserID }
);
}
这有效,并且完全按照我想要的方式工作:
domain.com/[username]/Profile
domain.com/[username]/Bio
现在是有效的工作路线,并且它们可以将 UserID 作为控制器中的方法参数,因为每个用户都有自己的路线。此外,默认路由仍然有效。耶。
我的问题是,这疯了吗?我正在为系统中的每个用户在路由表中创建一个条目。多少条路线太多?如果有超过 10 个用户,这会杀死我的服务器吗? 50? 1000?
如果这太疯狂了,我还能怎样实现这个目标呢?
提前致谢。我期待着来自蜂巢思维的一些意见。
Here is my dilemma. I have a collection of entities that I want to use to define as the starting point for a set of routes. For example, I want to give all of the users in my site their own "subsites" of the form mydomain.com/username, and then hang all of the UserController actions off of that.
Here is a rough example of what I am doing:
I have a "UserController", with action methods like "Index", "Profile" and "Bio".
public ActionResult Profile( int UserID )
{
User u = User.SingleOrDefault(u => u.UserID == UserID);
return View(u);
}
In RegisterRoutes() method, I do this:
foreach (User user in User.Find(u => u.Active == true))
{
routes.MapRoute(
"",
user.UserName + "/{action}",
new { controller="User", action="Index", UserID=user.UserID }
);
}
This works, and it works exactly as I want it to:
domain.com/[username]/Profile
domain.com/[username]/Bio
are now valid, working routes, and they can take in the UserID as the method parameter in the controller because each user gets their own route. Also, the default routes still work. Yay.
My question is, is this insane? I am creating an entry in the route table for every user in the system. How many routes is too many? Will this kill my server if there are over 10 users? 50? 1000?
And if this is insane, how else might I accomplish this goal?
Thanks in advance. I look forward to some input from the hive-mind.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我对你的做法有很多担忧。如果某人的用户名与您的其他控制器名称之一匹配怎么办?您将永远无法调用该控制器。此外,路由系统(据我所知)会按顺序测试所有路由,这意味着数千条路由将开始减慢路由查找速度,包括生成 URL(如
Url.Content()
或 <代码>Route.GetVirtualPath())。您不能将
用户名作为参数的一部分传递吗?如果每条路由都前往相同的控制器和操作方法,那么为每个用户生成路由有什么意义呢?
如果您需要仅匹配用户控制器,考虑实现自定义路由约束。该链接提供了创建控制器参数必须匹配的值列表的示例,但您可以轻松地为操作方法名称执行此操作。或者,您的自定义约束代码可以在数据库中查找用户名以查看其是否匹配。
There are a lot of concerns with your approach in my mind. What if someone has a username that matches one of your other controller names? You would never be able to call into that controller. Additionally, the routing system (as I understand it), tests all routes sequentially, meaning that thousands of routes would start to slow down routing lookups, including generation of Urls (like
Url.Content()
orRoute.GetVirtualPath()
).Can't you just do
and pass in the username as part of your parameters? What's the point of generating routes for each user if every route is going to the same controller and action methods?
If you need that to only match the User controller, consider implementing a custom route constraint. The link provides an example of creating a list of values that the controller parameter must match, but you could easily do it for your Action method names. Alternately, your custom constraint code could look up a username in the database to see if it matched.
另一种方法是考虑在
MapRoute()
中使用约束。保持routes.MapRoute("", "{UserName}/{action}", new {controller="user", action="Index", UserID=user.UserID});的值相同>,但添加 UserName 需要采用特定格式或列表的约束。
我不知道它是否会更高效,但它是注册许多(几乎相同)路由的替代方案。而且由于限制,它不会与默认路由冲突,无论如何您都应该将其作为最后一个 MapRoute() 调用,因此将首先评估这些路由。
An alternative approach would be looking at using constraints in your
MapRoute()
. Keep the same values ofroutes.MapRoute("", "{UserName}/{action}", new { controller="user", action="Index", UserID=user.UserID});
, but add the contraint that UserName needs to be in a specific format or in a list.I don't know if it will be more performant, but it is an alternative to registering that many (nearly identical) routes. And because of the constraint it won't conflict with the default route, which you should have as the last
MapRoute()
call anyways, so these will be evaluated first.我不确定您的限制是什么,但路由系统的构建是为了允许您使用一条路由而不是为每个用户一条路由来完成此操作。
基于您自己的一个非常简单的示例是:
I'm not sure what your limitations are, but the Routing system is built to allow you to do this with one route rather than one for each user.
A very simple example based on your own would be: