ASP.NET MVC 3.0 Маршрутизация поведения - PullRequest
0 голосов
/ 02 сентября 2011

У меня есть контроллер BlogController с парой действий:

1)Index(string id) - show all posts/show single post if parameter id specified
2)New() - add new post
3)Delete() - delete post
4)And some more another actions

Так что, если я наберу в браузере mysite/blog, я смогу увидеть все сообщения, если наберу mysite/blog/postnameid Я хочу увидеть одно сообщение.

проблема в том, что когда я печатаю mysite/blog/postnameid, это не работает (The resource cannot be found.), но если я набираю mysite/blog/index/postnameid, то это работает.Как я мог заставить mysite/blog/postnameid работать так же.

Вот мой маршрут блога в global.ascx

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

 routes.MapRouteLowercase(
               "Blog", // Route name
               "Blog/{action}/{id}", // URL with parameters
               new { controller = "Blog", action = "Index" } // Parameter defaults
            );

            routes.MapRouteLowercase(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
            );

Чем, если я его так изменить

routes.MapRouteLowercase(
               "Blog", // Route name
               "Blog/{id}", // URL with parameters
               new { controller = "Blog", action = "Index" } // Parameter defaults
            );

mysite/blog/postnameid работает, но все другие действия, такие как New (), Delete () перестают работать после этого (The resource cannot be found.)

UPDATE: Я забыл упомянуть, что id является stingне инт.поэтому из ответа @Darin я изменил new { id = @"\w+" } на new { id = @"\d+" } и все швы работали, но теперь, когда я набрал blog/new, например, он перенаправляется на show/new insteard blog/new

1 Ответ

2 голосов
/ 02 сентября 2011

Это плохая идея и против соглашений RESTful иметь одно действие контроллера, которое выполняет 2 действия и, конечно, нарушает принцип единой ответственности (перечислите все сообщения, если идентификатор не указан, и покажите данное сообщение, если идентификатор указан) , Правильный способ будет иметь следующее:

  • /blog => BlogController / Index => список всех сообщений
  • /blog/123 => BlogController / Show (id = 123) => показать детали данного сообщения
  • /blog/new => BlogController / New () => начать писать новый пост
  • /blog/delete/123 => BlogController / Delete (id = 123) => удалить данное сообщение

, что достигается следующими маршрутами:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Blog",
        "blog/{id}",
        new { controller = "Blog", action = "Show" },
        new { id = @"\d+" }
    );

    routes.MapRoute(
        "Default",
        "blog/{action}/{id}",
        new { controller = "Blog", action = "Index", id = UrlParameter.Optional }
    );
}

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

Это, как говорится, если вы хотите нарушить 2 принципа, которые я упомянул ранее и у вас есть маршруты, которые вы хотите, потребуется небольшая адаптация:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        "Blog",
        "blog/{id}",
        new { controller = "Blog", action = "Index" },
        new { id = @"\d+" }
    );

    routes.MapRoute(
        "Default",
        "blog/{action}/{id}",
        new { controller = "Blog", action = "Index", id = UrlParameter.Optional }
    );
}

Сейчас:

  • /blog => BlogController / Index (id = null) => список всех сообщений
  • /blog/123 => BlogController / Index (id = 123) => показать детали данного сообщения
  • /blog/new => BlogController / New () => начать писать новое сообщение
  • /blog/delete/123 => BlogController / Delete (id = 123) => удалить данное сообщение
...