Подтвердить что ты не робот

Настройка ASP.NET Web Api Routing

У меня есть контроллеры WebApi, которые заканчиваются суффиксом "Api" в их именах (например: StudentsApiController, InstructorsApiController). Я делаю это, чтобы легко отличить контроллеры MVC от контроллеров WebApi. Я хочу, чтобы мои маршруты WebApi выглядели похожими на

http://localhost:50009/api/students/5, а не http://localhost:50009/api/studentsapi/5.

В настоящее время для этого я настраиваю маршруты, например

routes.MapHttpRoute(
name: "GetStudents",
routeTemplate: "api/students/{id}",
defaults: new { controller = "StudentsApi", id = RouteParameter.Optional });

routes.MapHttpRoute(
name: "GetInstructors",
routeTemplate: "api/instructors/{id}",
defaults: new { controller = "InstructorsApi", id = RouteParameter.Optional });

Это оказывается очень громоздким, поскольку я должен добавить маршрут для каждого метода в своих контроллерах. Я надеюсь, что должен быть простой способ настройки шаблонов маршрутов, который автоматически добавляет суффикс "api" имя контроллера во время обработки маршрутов.

4b9b3361

Ответ 1

Я думаю, что точка расширяемости, которую вы ищете, - это селектор контроллера. Вы можете создать класс, который выводится из DefaultHttpControllerSelector и переопределяет имя GetControllerName, чтобы вырезать часть "api". Затем вы можете зарегистрировать этот селектор контроллера в службах конфигурации службы.

Ответ 2

Следуя @Youssef Moussaoui направлении, я закончил тем, что написал следующий код, который решил проблему.

public class ApiControllerSelector : DefaultHttpControllerSelector
{
    public ApiControllerSelector(HttpConfiguration configuration)
        : base(configuration)
    {
    }

    public override string GetControllerName(HttpRequestMessage request)
    {
        if (request == null)
            throw new ArgumentNullException("request");

        IHttpRouteData routeData = request.GetRouteData();

        if (routeData == null)
            return null;

        // Look up controller in route data
        object controllerName;
        routeData.Values.TryGetValue("controller", out controllerName);

        if (controllerName != null)
            controllerName += "api";

        return (string)controllerName;
    }
}

И зарегистрируйте его в Global.asax как

GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector),
            new ApiControllerSelector(GlobalConfiguration.Configuration));

Ответ 3

Теперь, когда ASP.NET Web API 2 отсутствует, существует гораздо менее громоздкий способ сделать более сложную маршрутизацию, как вы предложили, используя маршрутизацию атрибутов.

В верхней части вашего контроллера просто добавьте следующий атрибут:

[RoutePrefix("api/students")]
public class StudentsApiController : ApiController
{
    ...
}

И затем перед каждым методом API:

[Route("{id}"]
public HttpResponseMessage Get(int id)
{
    ...
}

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

Ответ 4

После комментария Youssef к муругу-ответу будет выглядеть примерно так.

public class ApiControllerSelector : DefaultHttpControllerSelector
{
    public ApiControllerSelector (HttpConfiguration configuration) : base(configuration) { }

    public override string GetControllerName(HttpRequestMessage request)
    {
        return base.GetControllerName(request) + "api";
    }
}