Маршрутизация действий на контроллере по умолчанию в ASP.NET MVC

У меня есть маршрутизация по умолчанию, поэтому, если я захожу на www.domain.com/app/, это, например, HomeController. У меня есть другое действие на элементе управления, например. helloworld, но если я зайду на www.domain.com/app/helloworld, он выйдет из строя с ошибкой 404 (без сомнения, ожидая контроллера helloworld).

Как я могу использовать действия не по умолчанию на моем контроллере по умолчанию ИЛИ как я могу сопоставить URL /app/helloworld с действием helloworld. Моя маршрутизация выглядит так:

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

routes.MapRoute( //this fails with same 404 like it does when it's ommitted
"Hello", // Route name
"app/helloworld", // URL with parameters
new { controller = "Home", action = "HellowWorld", id = UrlParameter.Optional } // Parameter defaults
);

В основном мне нужно:

/app/ => Контроллер = Главная, Действие = Индекс

/app/helloworld => Controller = Home, Action = HelloWorld, not Controller = HelloWorld, Action — Index

/app/other => Контроллер = Другое, Действие = Индекс


person DaveO    schedule 18.08.2012    source источник


Ответы (2)


Замените 2 routes в вашем глобальном файле на это:

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

Затем убедитесь, что ваш HomeController содержит:

public ActionResult Index()
{
    return View();
}

public ActionResult HelloWorld()
{
    return View();
}

Это означает, что yoursite.com/app/ANYCONTROLLER/ANYACTION будет перенаправляться к контроллеру и действию (пока они существуют), а значение по умолчанию new { controller = "Home", action = "Index" означает, что если кто-то перейдет к yoursite.com/app/, он автоматически перенаправится к yoursite.com/app/Home/Index.

Если это не сработает, попробуйте удалить app/, чтобы это выглядело так:

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

То, что у вас было, выглядит так, как будто вы пытались направить yoursite.com/Home/Index, а второй маршрут был сформулирован неправильно, я не уверен, что он будет делать, но вместо "app/helloworld он должен был выглядеть как "app/HelloWorld/{action}/{id}", тогда new { controller = "Home", action = "HellowWorld" работал бы. Так что, если кто-то перейдет к yoursite.com/app, он автоматически отобразит yoursite.com/app/Home/HelloWorld. Надеюсь, это поможет прояснить некоторые вещи.

Это ответ, который вам нужен

По какой-то причине вы не хотите создавать новый контроллер для раздела hello world, ваш RegisterRoutes в файле Global должен выглядеть так:

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

        routes.MapRoute(
            "Hello World", // Route name
            "App/HellowWorld/{id}", // URL with parameters
            new { controller = "Home", action = "HelloWorld", id = UrlParameter.Optional }
            );

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

Хотя я бы не рекомендовал идти по этому пути.

person Garrett Fogerlie    schedule 18.08.2012
comment
Извините, это не работает. Я разъяснил свои потребности в маршрутизации выше. Спасибо - person DaveO; 18.08.2012
comment
@DaveO посмотри мое обновление и попробуй yoursite.com/app/home/helloworld - person Garrett Fogerlie; 18.08.2012
comment
@DaveO Я предполагаю, что это сработало; Мне любопытно узнать, почему вы не хотели создавать отдельный HelloWorld Controller, или вы в итоге пошли по этому пути? - person Garrett Fogerlie; 18.08.2012
comment
Я использовал ваш последний ответ. Мне не нужен еще один контроллер, так как у этого конкретного приложения есть только один, и это простой ответ на отправку формы. В любом случае, это сработало блестяще, спасибо! - person DaveO; 19.08.2012

Для этого вам нужен только один маршрут. Вместо жесткого кодирования действия сделайте его переменной, но включите значение по умолчанию:

routes.MapRoute( //this fails with same 404 like it does when it's ommitted
    "Hello", // Route name
    "app/{action}", // URL with parameters
    new { controller = "Home", action = "HelloWorld", id = UrlParameter.Optional } 
);

Таким образом, когда вы перейдете на www.domain.com/app/, будет выполнено действие по умолчанию (HelloWorld). Но вы все равно можете указать действия в маршруте как www.domain.com/app/someotheraction.

Кроме того, имейте в виду, что выбран первый подходящий маршрут... поэтому вам следует подумать о перемещении маршрута по умолчанию в конец или о его полном исключении. В примере www.domain.com/app/helloworld он соответствует маршруту по умолчанию с app в качестве контроллера и helloworld в качестве действия ( что, конечно, неверно, отсюда и 404).

person McGarnagle    schedule 18.08.2012
comment
Спасибо. Вы имеете в виду, что мне не нужны два вызова MapRoute? Я пробовал только вышеперечисленное, и он терпит неудачу с белым экраном. Изменение моего второго звонка на это все еще дает мне 404. - person DaveO; 18.08.2012
comment
@DaveO правильно: обычно я перемещаю первый маршрут в конец списка, чтобы он функционировал как запасной вариант, не вытесняя ваши основные маршруты. - person McGarnagle; 18.08.2012