Вопрос о маршрутизации ASP.NET MVC

Я должен быть плотным. Задав несколько вопросов о StackOverflow, я все еще не понимаю, когда дело доходит до захвата нового механизма маршрутизации, предоставляемого ASP.NET MVC. Я думаю, что я сузил проблему до очень простой, которая, если она будет решена, вероятно, позволит мне решить остальную часть моих проблем маршрутизации. Итак, вот оно:

Как бы вы зарегистрировали маршрут для поддержки URL-адреса, подобного Twitterу, для профилей пользователей?

www.twitter.com/username

Предположим, что необходимо также поддерживать:

  • маршрут по умолчанию {controller}/{action}/{id}.

  • URL-адреса, такие как:

    www.twitter.com/login
    www.twitter.com/register

Возможно ли это?

Ответ 1

Что насчет

routes.MapRoute(
    "Profiles",
    "{userName}",
    new { controller = "Profiles", action = "ShowUser" }
);

а затем в ProfilesController будет функция

public ActionResult ShowUser(string userName)
{
...

В функции, если не найдено ни одного пользователя с указанным именем пользователя, вы должны перенаправить на маршрут по умолчанию {controller}/{action}/{id} (здесь это будет просто {controller}).

Похоже, что www.twitter.com/login должен быть зарегистрирован до этого.

routes.MapRoute(
    "Login",
    "Login",
    new { controller = "Security", action = "Login" }
);

Ответ 2

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

Для вашей проблемы я бы зарегистрировал правила маршрутизации для каждой из специальных страниц, например "register" и "login" перед правилом имени пользователя.

Ответ 3

Вы можете справиться с этим в домашнем контроллере, но метод контроллера не будет очень изящным. Я предполагаю, что что-то вроде этого может работать (не проверено):

routes.MapRoute(
    "Root",
    "{controller}/{view}",
    new { controller = "Home", action = "Index", view = "" }
);

Затем в вашем HomeController:

public ActionResult Index(string view) {
    switch (view) {
        case "":
            return View();

        case "register":
            return View("Register");

        default: 
            // load user profile view
    }
}

Ответ 4

OK Я никогда не пробовал это, но попытался расширить класс RouteBase для работы с пользователями. Документы для RouteBase предполагают, что метод GetRouteData должен возвращать null, если он не соответствует текущему запросу. Вы можете использовать это, чтобы проверить, соответствует ли запрос одному из имен пользователей, которые у вас есть.

Вы можете добавить подкласс RouteBase, используя:

  routes.Add(new UserRouteBase());

Когда вы регистрируете маршруты.

Возможно, стоит изучить.

Ответ 5

Я думаю, что ваш вопрос похож на мой. Маршрутизация ASP.NET MVC

вот что ответил robert harvey.

routes.MapRoute( _
    "SearchRoute", _
    "{id}", _
    New With {.controller = "User", .action = "Profile", .id = ""} _

)

Ответ 6

Вот альтернативный способ регистрации стандартного маршрута:

1. Загрузите RiaLibrary.Web.dll и укажите его в своем веб-проекте ASP.NET MVC

2. Разверните методы контроллера с помощью атрибутов [Url]:

public SiteController : Controller
{
    [Url("")]
    public ActionResult Home()
    {
        return View();
    }

    [Url("about")]
    public ActionResult AboutUs()
    {
        return View();
    }

    [Url("store/{?category}")]
    public ActionResult Products(string category = null)
    {
        return View();
    }
}

BTW, '?' параметр "{? category}" означает, что он является необязательным. Вам не нужно будет указывать это явно в значениях по умолчанию маршрута, что равно этому:

routes.MapRoute("Store", "store/{category}",
new { controller = "Store", action = "Home", category = UrlParameter.Optional });

3. Обновить файл Global.asax.cs

public class MvcApplication : System.Web.HttpApplication
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoutes(); // This do the trick
    }

    protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
    }
}

Как установить значения по умолчанию и ограничения? Пример:

public SiteController : Controller
{
    [Url("admin/articles/edit/{id}", Constraints = @"id=\d+")]
    public ActionResult ArticlesEdit(int id)
    {
        return View();
    }

    [Url("articles/{category}/{date}_{title}", Constraints =
         "date=(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])")]
    public ActionResult Article(string category, DateTime date, string title)
    {
        return View();
    }
}

Как настроить порядок? Пример:

[Url("forums/{?category}", Order = 2)]
public ActionResult Threads(string category)
{
    return View();
}

[Url("forums/new", Order = 1)]
public ActionResult NewThread()
{
    return View();
}