Маршрутизация атрибутов не работает в областях
Сценарий: у меня есть область Forms на моем сайте ASP.NET MVC 5.
Я пытаюсь перенаправить на действие "Сведения", которое использует настраиваемый маршрут, определенный с помощью новой функции маршрутизации атрибутов.
RedirectToAction:
return RedirectToAction("Details", new { slug });
Действие, к которому я перенаправляюсь:
[HttpGet]
[Route("forms/{slug}")]
public ActionResult Details(string slug)
{
var form = FormRepository.Get(slug);
...
return View(model);
}
Я бы ожидал перенаправления на http://localhost/forms/my-slug
, но вместо этого приложение перенаправляет меня на http://localhost/Forms/Details?slug=my-slug
.
Это означает, что маршрутизация атрибутов не работает.
Как это можно решить?
Я добавил маршруты .MapMvcAttributeRoutes(); line к моему RouteConfig:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
И вот мой Application_Start():
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
Ответы
Ответ 1
Вероятно, вы комбинируете маршрутизацию на основе конвенций с маршрутизацией атрибутов, и вы должны зарегистрировать свои области после сопоставления маршрутов атрибутов.
Линия
AreaRegistration.RegisterAllAreas();
следует вызвать ПОСЛЕ этой строки:
routes.MapMvcAttributeRoutes();
Объяснение (из http://blogs.msdn.com/b/webdev/archive/2013/10/17/attribute-routing-in-asp-net-mvc-5.aspx#route-areas):
Если вы используете обе области с атрибутами маршрута и областями с условными маршрутами (заданными классом AreaRegistration), то вам необходимо убедиться, что регистрация области происходит после настройки маршрутов атрибутов MVC, однако до того, установленный маршрут. Причина заключается в том, что регистрация маршрута должна быть заказана из наиболее специфических (атрибутов) посредством более общей (регистрации области) в общий тип тумана (маршрут по умолчанию), чтобы избежать использования общих маршрутов из "скрытия" более конкретных маршрутов путем сопоставления входящих запросов слишком рано трубопровод.
Когда вы создаете пустой веб-сайт asp.net mvc, добавьте область и начнете использовать маршрутизацию атрибутов, вы столкнетесь с этой проблемой, потому что действие "Add Area" в visual studio добавляет вызов RegisterAllAreas в вашем Application_Start до конфигурации маршрута..
Альтернативное решение
Возможно, вы не собираетесь продолжать использовать маршрутизацию на основе условных обозначений и предпочитаете использовать маршрутизацию атрибутов.
В этом случае вы можете просто удалить файл FormsAreaRegistration.cs.
Ответ 2
Перемещение областиRegistration.RegisterAllAreas() в RouteConfig.cs было недостаточно для меня. Мне также необходимо было использовать параметр AreaPrefix для Attribute RouteArea:
//Use the named parameter "AreaPrefix"
[RouteArea("AreaName", AreaPrefix = "area-name-in-url")]
[RoutePrefix("controller-name-in-url")]
public class SampleController : Controller
{
[Route("{actionParameter}")]
public ActionResult Index(string actionParameter)
{
return View();
}
}
Изменить: В какой-то момент я столкнулся с образцовым решением от Microsoft, которое прекрасно показало, как обрабатывать маршрутизацию атрибутов. Он также показал несколько хороших примеров того, как перевести SelectList
в массив элементов input[type="radio"]
, а также сделать то же самое с массивом элементов input[type="checkbox"]
(если я помню). Это примерное решение, вероятно, является лучшим ответом на этот вопрос, а также дает несколько хороших примеров при отображении переключателей и элементов флажка. Если кто-нибудь знает об этом образце решения, добавьте комментарий со ссылкой на него.