Маршруты MVC в контроллере WebAPI

Быстрый вопрос о маршрутах в MVC и WebAPI. Я добавил маршрут в route config.cs:

        routes.MapRoute(
            name: "ConfirmEmail",
            url: "ConfirmEmail/{userid}",
            defaults: new { controller = "Email", action = "ConfirmEmail" }
        );

Это зарегистрировано в global.asax как обычно:

RouteConfig.RegisterRoutes(RouteTable.Routes);

Я пытаюсь создать URL-адрес для использования в электронном письме, которое отправляется как часть вызова функции в функции контроллера WebAPI. Я использую функцию UrlHelper.Link, чтобы попытаться сгенерировать URL-адрес, однако получаю сообщение об ошибке, в котором говорится, что маршрут не может быть найден по имени:

var url = Url.Link("ConfirmEmail", new { userid = "someUserId" });

Теперь у меня сложилось впечатление, что словари маршрутов были общими как в контекстах контроллера MVC, так и в WebAPI, однако я не вижу маршруты MVC в словаре маршрутов входящего вызова Web API (в объекте запроса), однако определенные мной маршруты WebAPI есть.

Я что-то упускаю?


person Graham Whitehouse    schedule 19.03.2015    source источник


Ответы (3)


Таблицы маршрутизации для MVC и Web API совершенно разные. Хотя синтаксис выглядит одинаково, таблица маршрутов, с которой они работают, отличается.

Однако MVC использует статические объекты для настройки, поэтому вы можете получить доступ к глобальной таблице маршрутов MVC из контроллера API, используя System.Web.Routing.RouteTable.Routes.

Однако это не позволит вам использовать Url.Link, поэтому я бы предложил использовать константу в вашей регистрации маршрута для формата.

person Richard    schedule 19.03.2015
comment
Да, я думал, что это так... Интересно, что вы можете сгенерировать URL-адрес веб-API в представлении MVC, используя таблицы маршрутизации... Ну ладно! - person Graham Whitehouse; 20.03.2015

Вот гораздо более чистый способ создания ссылок на маршруты MVC из WebApi. Я использую этот метод в пользовательском базовом API-контроллере.

protected string MvcRoute(string routeName, object routeValues = null)
{
    return new System.Web.Mvc.UrlHelper(System.Web.HttpContext.Current.Request.RequestContext)
       .RouteUrl(routeName, routeValues, System.Web.HttpContext.Current.Request.Url.Scheme);

}
person Owre    schedule 01.09.2015
comment
Работал как шарм для меня. - person shaun; 07.12.2015

Используя подсказку Ричарда о том, где найти маршруты, я собрал следующую функцию:

    // Map an MVC route within ApiController
    private static string _MvcRouteURL(string routeName, object routeValues)
    {
        string mvcRouteUrl = "";

        // Create an HttpContextBase for the current context, used within the routing context
        HttpContextBase httpContext = new System.Web.HttpContextWrapper(HttpContext.Current);

        // Get the route data for the current request
        RouteData routeData = HttpContext.Current.Request.RequestContext.RouteData;

        // Create a new RequestContext object using the route data and context created above
        var reqContext = new System.Web.Routing.RequestContext(httpContext, routeData);

        // Create an Mvc UrlHelper using the new request context and the routes within the routing table
        var helper = new System.Web.Mvc.UrlHelper(reqContext, System.Web.Routing.RouteTable.Routes);

        // Can now use the helper to generate Url for the named route!
        mvcRouteUrl = helper.Action(routeName, null, routeValues, HttpContext.Current.Request.Url.Scheme);

        return mvcRouteUrl;
    }

Это немного сыро, но сработало для меня, просто подумал, что поместил это здесь на случай, если у кого-то еще будет такая же проблема!

person Graham Whitehouse    schedule 20.03.2015