Reputation: 896
I cannot for the life of me understand why this isn't working.
I have a simple ASP.Net MVC Web API controller, with 2 get methods. I have an AngularJS service with 2 corresponding functions. The GetAllRisks works perfectly well. However, the GetRiskByID comes back with an error saying "No HTTP request was found that matches the request "http://localhost:49376/api/RiskApi/GetRiskByID/6" and "No action can be found on the RiskApi controller that matches the request."
The URL is being passed correctly. I have tried various options for the API routing but can't get anywhere. I am sure I am missing something simple but can't see it.
I would really appreciate any thoughts.
Thanks,
Ash
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 }
);
}
}
Upvotes: 0
Views: 3010
Reputation: 3164
...try junking your config's HttpRoute
Mapping and introduce the route mapping with Attributes.
Since this is first-gen Web API, you'll need to pull in the AttributeRouting.WebAPI NuGet package, and you'll likely want to refer here(strathweb) for straightforward guidance on how to implement.
Note that you have a mapping problem in your current implementation on your {id}
parameter: you declare it to be id in the route configuration, but then you identify it as riskID
inside the controller's method; these need to match. Switch your controller's method to have its incoming routeParameter be named id
. You could optionally switch your config to declare the {riskID}
parameter in your routes, but that would couple your global configuration to the semantics of a specific controller and you'd likely need to implement more routing constraints to have other controllers not named "Risk" make sense.
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;
}
}
Upvotes: 0
Reputation: 5571
Try changing your WebApiConfig class to:
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 }
);
}
}
And change your param: riskID
to 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;
}
Then, you could use:
// GET: api/RiskApi/GetAllRisks
// GET: api/RiskApi/GetRiskByID/5
Upvotes: 3