Динамически генерировать много маршрутов в ASP.NET MVC ... это вообще плохая идея? - PullRequest
4 голосов
/ 20 января 2010

Вот моя дилемма. У меня есть набор сущностей, которые я хочу использовать для определения в качестве отправной точки для набора маршрутов. Например, я хочу предоставить всем пользователям на моем сайте свои собственные «дочерние сайты» в форме 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

теперь являются действующими рабочими маршрутами, и они могут принимать идентификатор пользователя в качестве параметра метода в контроллере, поскольку каждый пользователь получает свой собственный маршрут. Кроме того, маршруты по умолчанию все еще работают. Yay.

Мой вопрос: это безумие? Я создаю запись в таблице маршрутов для каждого пользователя в системе. Сколько маршрутов это слишком много? Это убьет мой сервер, если будет более 10 пользователей? 50? 1000

И если этот безумен, как еще я мог бы достичь этой цели?

Заранее спасибо. Я с нетерпением жду каких-то отзывов от улья.

Ответы [ 3 ]

10 голосов
/ 20 января 2010

Есть много проблем с вашим подходом в моей голове.Что если у кого-то есть имя пользователя, совпадающее с одним из имен других ваших контроллеров?Вы никогда не сможете позвонить в этот контроллер.Кроме того, система маршрутизации (насколько я понимаю) последовательно тестирует все маршруты, что означает, что тысячи маршрутов начнут тормозить поиск маршрутов, включая генерацию URL (например, Url.Content() или Route.GetVirtualPath()).

Вы не можете просто сделать

/{username}/{action}

и передать имя пользователя как часть ваших параметров?Какой смысл генерировать маршруты для каждого пользователя, если каждый маршрут идет к одному и тому же контроллеру и методам действия?

Если вам нужно, чтобы это соответствовало только пользовательскому контроллеру, рассмотрите возможность реализации пользовательского ограничения маршрута .Ссылка предоставляет пример создания списка значений, которым должен соответствовать параметр контроллера, но вы можете легко сделать это для имен ваших методов Action.С другой стороны, ваш пользовательский код ограничения может найти имя пользователя в базе данных, чтобы определить, соответствует ли оно.

2 голосов
/ 20 января 2010

Альтернативный подход будет рассматривать использование ограничений в MapRoute().Оставьте те же значения routes.MapRoute("", "{UserName}/{action}", new { controller="user", action="Index", UserID=user.UserID});, но добавьте ограничение, что UserName должен быть в определенном формате или в списке.

Я не знаю, будет ли он более производительным, но это альтернативадля регистрации такого количества (почти идентичных) маршрутов.И из-за ограничения он не будет конфликтовать с маршрутом по умолчанию, который вы должны иметь в качестве последнего MapRoute() вызова в любом случае, поэтому они будут оценены первыми.

0 голосов
/ 20 января 2010

Я не уверен, каковы ваши ограничения, но система маршрутизации построена таким образом, чтобы вы могли делать это с одним маршрутом, а не с одним для каждого пользователя.

Очень простой пример, основанный на вашем собственномбыть:

routes.MapRoute(
         "",
         "{UserName}/{action}",
         new { controller="User", action="Index", UserID=user.UserID }
     );
...