Я не могу, чтобы жизнь меня поняла, почему это не работает.
У меня есть простой ASP.Net MVC Web API-контроллер с двумя методами get. У меня есть служба AngularJS с двумя соответствующими функциями. GetAllRisks работает отлично. Однако GetRiskByID возвращается с ошибкой: "HTTP-запрос не найден, который соответствует запросу" http://localhost: 49376/api/RiskApi/GetRiskByID/6 "и" Никакое действие не может быть найдено на контроллере RiskApi, который соответствует запрос."
URL-адрес передается правильно. Я пробовал различные варианты маршрутизации API, но никуда не могу. Я уверен, что я пропустил что-то простое, но не вижу его.
Я бы очень признателен за любые мысли.
Благодаря,
ясень
RiskApiController
public class RiskApiController : ApiController
{
private readonly IRiskDataService _riskDataService;
public RiskApiController(IRiskDataService riskDataService)
{
_riskDataService = riskDataService;
}
// GET api/RiskApi
[HttpGet]
public IEnumerable<IRisk> GetAllRisks()
{
return _riskDataService.GetAllRisks().Take(20);
}
// GET api/RiskApi/5
[HttpGet]
public IRisk GetRiskByID(int riskID)
{
IRisk risk = _riskDataService.GetRiskByID(riskID);
if (risk == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
return risk;
}
}
service.js
app.service('OpenBoxExtraService', function ($http) {
//Get All Risks
this.getAllRisks = function () {
return $http.get("/api/RiskApi/GetAllRisks");
}
//Get Single Risk by ID
this.getRisk = function (riskID) {
var url = "/api/RiskApi/GetRiskByID/" + riskID;
return $http.get(url);
}
});
WebApiConfig
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "ActionRoute",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Попробуйте изменить класс WebApiConfig следующим образом:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
И измените свой параметр: riskID
на id
.
// GET: api/RiskApi/GetRiskByID/5
[HttpGet]
public IRisk GetRiskByID(int id)
{
IRisk risk = _riskDataService.GetRiskByID(id);
if (risk == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
return risk;
}
Затем вы можете использовать:
// GET: api/RiskApi/GetAllRisks
// GET: api/RiskApi/GetRiskByID/5
... попробуйте загрузить свой конфигуратор HttpRoute
Сопоставление и ввести сопоставление маршрутов с атрибутами.
Поскольку это веб-API первого поколения, вам нужно будет вытащить пакет AttributeRouting.WebAPI NuGet, и вы, вероятно, захотите обратиться сюда (strathweb) для простого руководства по его реализации.
Обратите внимание, что у вас есть проблема с отображением в вашей текущей реализации по вашему параметру {id}
: вы объявляете ее идентификатором в конфигурации маршрута, но затем вы определяете ее как riskID
внутри метода контроллера; они должны соответствовать. Переключите свой метод контроллера, чтобы его входящий routeParameter назывался id
. Вы можете по желанию переключить свой {riskID}
чтобы объявить параметр {riskID}
в своих маршрутах, но это {riskID}
бы вашу глобальную конфигурацию с семантикой определенного контроллера, и вам, скорее всего, потребуется реализовать больше ограничений маршрутизации, чтобы другие контроллеры не назывались "Risk "Имеют смысл.
public class RiskApiController : ApiController
{
private readonly IRiskDataService _riskDataService;
public RiskApiController(IRiskDataService riskDataService)
{
_riskDataService = riskDataService;
}
// GET api/RiskApi
[HttpGet]
[Route("api/RiskApi")]
public IEnumerable<IRisk> GetAllRisks()
{
return _riskDataService.GetAllRisks().Take(20);
}
// GET api/RiskApi/5
[HttpGet]
[Route("api/RiskApi/{id}")]
public IRisk GetRiskByID(int id)
{
IRisk risk = _riskDataService.GetRiskByID(id);
if (risk == null)
{
throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
}
return risk;
}
}
/api/RiskApi/foo
? Он будет соответствовать маршруту api / {controller} / {id}, а также маршруту api / {controller} / {action} / {id}, так как у вас есть {id} необязательный для обоих. Маршрутизатор не сможет определить, является ли foo значением {id} или {action}. Естественно, он не сможет отправить «foo» как int для идентификатора, но я не уверен, достаточно ли интеллектуален маршрутизатор, чтобы сделать вывод, что маршрут на основе {action} - это тот, который вам нужен. Я думаю, что это просто не удастся проложить маршрут.