The Dumb Radish
The Dumb Radish

Reputation: 896

AngularJS web api call - can't find get method on controller

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

Answers (2)

K. Alan Bates
K. Alan Bates

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

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

Related Questions