Сбой маршрутизации Web API 2 для литерального сегмента

Я столкнулся с проблемой маршрутизации Web API 2 для литеральных сегментов.

В одном проекте у меня есть ASP.NET MVC и WebAPI2, работающие вместе, проект также использует области MVC.

В каждой области есть папка API, содержащая API. Я столкнулся с проблемой при попытке запросить следующий URL-адрес: {host}/accesscontrol/api/reporting/bookings.

  • управление доступом здесь имя области
  • отчетность является контролером
  • бронирования — это буквальный сегмент.

Я получаю сообщение об ошибке: Для контроллера «Отчетность» не найдено действие, соответствующее запросу.

Это контроллер, который должен получить этот запрос:

[RoutePrefix("accesscontrol/api/reporting")]
public class ReportingController : ApiController
{
    [Route("bookings")]
    [ResponseType(typeof(Booking))]
    [HttpGet]
    public async Task<IHttpActionResult> Bookings(string q = null)
    {
        //Code to get data
        return Ok(bookings);
    }
}

Когда я удаляю атрибут [Route('Bookings')], запрос работает хорошо, независимо от того, есть ли там сегмент Bookings или нет.

Это конфигурация маршрутизации в классе регистрации области:

public override void RegisterArea(AreaRegistrationContext context)
{
    context.Routes.MapHttpRoute(
        "AccessControlApi_default",
        "accesscontrol/api/{controller}/{id}",
        new { id = RouteParameter.Optional }
        );

    context.MapRoute(
        "AccessControl_default",
        "accesscontrol/{controller}/{action}/{id}",
        new { action = "Index", id = UrlParameter.Optional }
    );
}

Как я могу позволить приложению понимать эти буквальные сегменты под областями?

Редактировать

Я вызываю RegisterAllAreas в файле Global.asax.cs следующим образом:

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        GlobalConfiguration.Configure(WebApiConfig.Register);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
    }
}

comment
Можете попробовать изменить [Route(bookings)] на [Route(bookings/{q?})] и посмотреть, будет ли это иметь какое-то значение?   -  person valentin    schedule 23.04.2015
comment
@valentin Я пробовал, та же ошибка!   -  person AlBaraa Sh    schedule 23.04.2015


Ответы (2)


Мне удалось заставить его работать, просто добавьте действие после вашего контроллера в ваш MapHttpRoute и измените атрибут [Route("bookings")] на [ActionName("bookings")] и все работает.

  context.Routes.MapMvcAttributeRoutes();

  context.Routes.MapHttpRoute(
      "AccessControlApi_default",
      "Accesscontrol/api/{controller}/{action}/{id}",
      new { id = RouteParameter.Optional});

Я надеюсь, что это поможет вам.

person jtabuloc    schedule 23.04.2015
comment
Я прочитал это, и это точно применено. Я не знаю, где проблема. - person AlBaraa Sh; 23.04.2015
comment
попробуйте добавить это в свой RegisterArea context.Routes.MapMvcAttributeRoutes();, это позволит маршрутизировать атрибуты. - person jtabuloc; 23.04.2015
comment
Я сделал, я добавил его перед всем остальным кодом сопоставления, но с тем же результатом ошибки! - person AlBaraa Sh; 23.04.2015
comment
Я попытался создать свой собственный проект, и кажется, что все работает нормально, пока я не заметил, что вы создаете свой собственный класс регистрации. Я думаю, что на этот вопрос уже есть ответ здесь. - person jtabuloc; 23.04.2015
comment
@AlBaraa Sh, мне удалось заставить это работать, и я пересмотрел свой ответ. Я надеюсь, что это поможет вам. - person jtabuloc; 23.04.2015
comment
У меня есть другие API REST, так что не должно быть никаких действий, чтобы они работали, верно? - person AlBaraa Sh; 23.04.2015
comment
Моя проблема только в буквальных сегментах! - person AlBaraa Sh; 23.04.2015
comment
Эти URL-адреса работают нормально: accesscontrol/api/people/{id}/activate, это просто проблема сопоставления!! - person AlBaraa Sh; 23.04.2015

Я решил проблему, переместив: AreaRegistration.RegisterAllAreas(); из файла global.asax.cs в файл RouteConfig.cs.

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

        AreaRegistration.RegisterAllAreas();

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            namespaces:  new[] {"WebPortal.Controllers"}
        );
    }
}
person AlBaraa Sh    schedule 26.04.2015