Пользовательский вызов метода из WebAPI
Итак, я собираю доказательство прототипа концепции для приложения WebAPI, и все обычные методы работают отлично. Но я также хотел продемонстрировать возможность вызова пользовательских методов через WebAPI. Итак, у меня есть следующая маршрутизация в моем RouteConfig.cs:
routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
В контроллере у меня есть простой метод:
[HttpGet]
public string Test()
{
return "this is a string";
}
Когда я пытаюсь вызвать мой метод: http://localhost:43225/api/values/test
Я получаю следующую ошибку в браузере:
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.String Get(Int32)' in 'WebAPI_Listener.Controllers.ValuesController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter.
</string>
Но если я укажу идентификатор в конце URL, например, http://localhost:43225/api/values/test/1
это работает, даже если сам метод не принимает параметр вообще.
Так что в маршрутизации, если у меня установлен id} как необязательный, почему он не работает, когда я не указываю {id}, но работает, если я это сделаю, даже если сам метод не ожидает { Я бы}??
1 ответ
Вам необходимо объявить свои маршруты API в методе регистрации ~/App_Start/WebAPIConfig.cs. Маршрут catchall в WebAPIConfig предшествует маршрутам RouteConfig, поэтому ваш маршрут никогда не выбирается.
Вот пример добавления маршрута, похожего на ваш, в WebAPIConfig. Недостаток этого примера: вы должны явно указать HTTP-глаголы для контроллера, который соответствует этому маршруту (то есть ~/api/values /get/5 вместо ~/localhost:43225/api/values /5).
config.Routes.MapHttpRoute(
name: "CustomAPIActions",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Чтобы избежать этого недостатка, вы можете ограничить маршрут до данного контроллера следующим образом:
config.Routes.MapHttpRoute(
name: "ApiNonCrudActionsForMyController",
routeTemplate: "MyController/{action}/{id}",
defaults: new { controller = "MyController", id = RouteParameter.Optional }
);
Вы также можете ограничить маршрут к контроллеру и действию, чтобы сохранить стандартные глаголы, но это может стать проблемой обслуживания или путаницей, если вы делаете это много.
config.Routes.MapHttpRoute(
name: "ApiNonCrudActionsForMyController",
routeTemplate: "MyController/Test/{id}",
defaults: new { controller = "MyController", action = "Test", id = RouteParameter.Optional }
);
Для получения дополнительной информации и некоторых других подходов, проверьте это: http://encosia.com/rest-vs-rpc-in-asp-net-web-api-who-cares-it-does-both/. Вы также можете ограничить действие HTTP-глаголами и добавить дополнительные контроллеры для пользовательских действий (например, ~/localhost:43225/api/TestValues /5).