Маршрутизация asp.net MVC: как использовать действие по умолчанию, но не параметр по умолчанию? - PullRequest
17 голосов
/ 08 апреля 2011

Я переписываю вопрос, так как ответы пока что показывают мне, что я недостаточно хорошо его определил.Я оставлю исходный вопрос для справки ниже.

При настройке маршрутизации вы можете указать значения по умолчанию для различных частей URL / маршрута.Рассмотрим пример, который мастер VS генерирует:

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

В этом примере, если контроллер не указан, будет использоваться DefaultPageController, а если действие не указано, будет использовано действие «Индекс».URL обычно выглядят так: http://mysite/MyController/MyAction.

Если в Url нет действия, подобного этому: http://mysite/MyController, тогда будет использовано действие индекса.

Теперь давайте предположим, что у меня есть двадействия в моем контроллере Index и AnotherAction.Соответствующие им URL-адреса http://mysite/MyController и http://mysite/MyController/AnotherAction соответственно.Мое действие «Индекс» принимает параметр, идентификатор.Поэтому, если мне нужно передать параметр в действие Index, я могу сделать это: http://mysite/MyController/Index/123.Обратите внимание, что в отличие от URL http://mysite/MyController, я должен явно указать действие Index.Что я хочу сделать, так это уметь передавать http://mysite/MyController/123 вместо http://mysite/MyController/Index/123.Мне не нужен индекс в этом URL. Я хочу, чтобы механизм mvc распознал, что когда я запрашиваю http://mysite/MyController/123, 123 - это не действие (потому что я не определил действие с этим именем), а параметр длямое действие по умолчанию "Индекс".Как мне настроить маршрутизацию для достижения этой цели?

Ниже приведена оригинальная формулировка вопроса.


У меня есть контроллер с двумя методами, определенными так:

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

    [HttpPost]
    public ActionResult Index(SomeFormData data)
    {
        return View();

    }

Это позволяет мне обрабатывать URL как http://website/Page как при переходе пользователя к этому URL (GET), так и при последующей отправке обратно формы (POST).

Теперь, когда я обрабатываю сообщение обратноВ некоторых случаях я хочу перенаправить браузер на этот URL:

http://website/Page/123

Где 123 - это целое число, и мне нужен метод для обработки этого URL в моем контроллере.

Как сделатьЯ настроил маршрутизацию, так что это работает?В настоящее время у меня есть маршрутизация «по умолчанию», сгенерированная мастером, как это:

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

Я попытался добавить другой метод контроллера, как это:

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

Но это не работает как неоднозначное действиегенерируется исключение:

Текущий запрос на действие «Индекс» для типа контроллера «PageController» неоднозначен между следующими методами действия: System.Web.Mvc.ActionResult Index () для типа PageController System.Индекс Web.Mvc.ActionResult (Int32) для типа PageController

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

Ответы [ 4 ]

11 голосов
/ 08 апреля 2011

Вот как это можно решить:

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

Рассмотрим этот код:

routes.MapRoute(
  "MyController", "MyController/{productId}", 
  new {controller="My", action="Index"}, 
  new {productId = @"\d+" });

Это определение маршрута будет соответствовать только числовым значениям после MyController в http://mysite/MyController/123, поэтому оно не будет мешать вызову другого действия на том же контроллере.

Источник: Создание ограничения маршрута

3 голосов
/ 08 апреля 2011

Если вы оставите имя переменной идентификатором, вам не нужно ничего менять.

Переименуйте сообщение в «PostIndex» и добавьте этот атрибут:

[ActionName("Index")]

Тот же вопрос по SO здесь .

Хорошо, вот вам ответ "вырезать / вставить", если это поможет.

public ActionResult Index()    {        
return View();    
}    
[AcceptVerbs(HttpVerbs.Post), ActionName("Index")]   
public ActionResult PostIndex(SomeFormData data)    {        
return View();    
}
2 голосов
/ 08 апреля 2011

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

    // /MyController/AnotherAction
    routes.MapRoute(
        null,
        "MyController/AnotherAction",
        new { controller = "DefaultPage", action = "AnotherAction" }
    );

    // /MyController
    // /MyController/id
    routes.MapRoute(
        null,
        "MyController/{id}",
        new { controller = "DefaultPage", action = "Index", id = UrlParameter.Optional }
    );

пс. Маршруты по умолчанию как / MyController / id должны быть отображены в конце.

0 голосов
/ 08 апреля 2011

Я думаю, что вы хотите вернуть тот же взгляд, но вы должны понимать, что вы делаете две разные вещи. Один из них получает почту, другой получает доступ через get, а другой - через get и параметр ...

Вы должны сделать 3 actionresult с разными именами и вернуть то же представление, что и View ("ThisIsTheResult")

...