Как исправить 404 с помощью маршрутов в ASP.NET MVC?
У меня возникла проблема с попыткой получить маршрутизацию для работы с ASP.NET MVC 3.0. У меня объявлены следующие маршруты:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "RsvpForm", id = UrlParameter.Optional }
);
routes.MapRoute(
"TestRoute",
"{id}",
new { controller = "Product", action = "Index3", id = UrlParameter.Optional }
);
routes.MapRoute(
"TestRoute2",
"{action}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Когда я посещаю:
http://localhost
Сайт работает правильно, и он попадает в маршрут Default
.
Когда я посещаю:
http://localhost/1
Я получаю 404:
Ошибка сервера в приложении "/".
Ресурс не найден. Описание: HTTP 404. Ресурс, который вы ищете (или его зависимости), мог быть удален, изменилось его имя или Временно недоступен. Просмотрите следующий URL-адрес и сделайте что это правильно написано.
Запрошенный URL:/1
Ниже перечислены действия, которые соответствуют этим маршрутам:
public ActionResult Index3(int? id)
{
Product myProduct = new Product
{
ProductID = 1,
Name = "Product 1 - Index 3",
Description = "A boat for one person",
Category = "Watersports",
Price = 275M
};
Product myProduct2 = new Product
{
ProductID = 2,
Name = "Product 2 - Index 3",
Description = "A boat for one person",
Category = "Watersports",
Price = 275M
};
ViewBag.ProcessingTime = DateTime.Now.ToShortTimeString();
if (id == 1)
return View("index", myProduct);
else
return View("index", myProduct2);
}
Как мне структурировать маршруты, чтобы все три метода действий попали правильно?
Ответы
Ответ 1
ASP.NET MVC Routing оценивает маршруты сверху вниз. Таким образом, если два маршрута совпадают, первый из них попадает (тот, который ближе к "вершине" метода RegisterRoutes
) будет иметь приоритет над последующим.
С учетом этого вам нужно сделать две вещи, чтобы исправить вашу проблему:
- Ваш маршрут по умолчанию должен быть внизу.
- В ваших маршрутах должны быть ограничения на них, если они содержат одинаковое количество сегментов:
Какая разница между:
example.com/1
и
example.com/index
В синтаксический анализатор они содержат одинаковое количество сегментов, и нет никакого отличия, поэтому он будет ударять по первому маршруту в списке, который соответствует.
Чтобы исправить это, вы должны убедиться, что маршруты, использующие ProductIds
, принимают ограничения:
routes.MapRoute(
"TestRoute",
"{id}",
new { controller = "Product", action = "Index3", id = UrlParameter.Optional },
new { id = @"\d+" } //one or more digits only, no alphabetical characters
);
Есть и другие проблемы с вашей настройкой, но это две вещи, которые приходят на ум сразу с места.
Ответ 2
Ваши маршруты MapRoute Значение по умолчанию должно быть последним.
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "RsvpForm", id = UrlParameter.Optional }
);
Ответ 3
Настройте самый общий маршрут до последней из цепочки вызовов MapRoute.
Попробуйте следующее:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"TestRoute",
"{id}",
new { controller = "Product", action = "Index3", id = UrlParameter.Optional }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "RsvpForm", id = UrlParameter.Optional } // Parameter defaults
//new { controller = "Product", action = "Index2", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"TestRoute2",
"{action}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Ответ 4
Переместите свой маршрут по умолчанию до конца. Маршрут по умолчанию должен быть последним маршрутом для определения, поскольку он действует как "поймать весь маршрут"
Ответ 5
В моем случае ответ на ту же проблему заключался в необходимости "включать в проект" соответствующие контроллеры и представления вместо неправильных правил маршрутизации.
Когда мои были созданы, они по какой-то причине не включались автоматически. Эта проблема была выявлена после закрытия и повторного открытия решения.
{+ 1 ненависть}, присужденная Visual Studio за ее ошибочную гипер-автоматизацию, отправив мне копать файлы Web.Config, пытаясь зацепиться за расширения, и даже пытаться (и терпеть неудачу) взломать приличный ErrorController.