Reputation: 1218
I really can't see what I am doing wrong here. I am trying to call a asp.net core web api method that accepts an integer via HttpClient
but it returns a 404
error.
HospitalController
(Web API)
[HttpGet("{id}")]
[Route("GetById")]
public JsonResult Get(int id)
{
return Json(_hospitalService.Get(id));
}
HospitalController
(MVC)
protected string url = "http://localhost:5001/api/Hospital";
[HttpGet]
public async Task<IActionResult> Edit(int id)
{
if (id.Equals(0))
return StatusCode(404);
var accessToken = await HttpContext.GetTokenAsync("access_token");
client.SetBearerToken(accessToken);
HttpResponseMessage responseMessage = await client.GetAsync(url + "/GetById/" + id); //returns 404 error here.
if (responseMessage.IsSuccessStatusCode)
{
var responseData = responseMessage.Content.ReadAsStringAsync().Result;
var hospital = JsonConvert.DeserializeObject<Hospital>(responseData);
var hospitalVM = Mapper.Map<HospitalViewModel>(hospital);
return View(hospitalVM);
}
return View("Error");
}
I have a POST method in the same controller in MVC that works. But this GET method returns a 404 and I can't seem to know why.
Upvotes: 4
Views: 3832
Reputation: 247631
There are two route templates being used in the api according to
[HttpGet("{id}")] //Matches GET api/Hospital/5
[Route("GetById")] //Matches GET api/Hospital/GetById
neither of which match what is being called
http://localhost:5001/api/Hospital/GetById/5
Http{Verb}
attribute is usually used on RestFul APIs.
When building a REST API, it's rare that you will want to use
[Route(...)]
on an action method. It's better to use the more specificHttp*Verb*Attributes
to be precise about what your API supports. Clients of REST APIs are expected to know what paths and HTTP verbs map to specific logical operations.
Reference Routing to Controller Actions
update the route template on the web api to map to the desired route
[Route("api/[controller]")]
public class HospitalController : Controller {
//...code removed for brevity
//Matches GET api/Hospital/GetById/5
[HttpGet("GetById/{id:int}")]
public IActionResult Get(int id) {
return Ok(_hospitalService.Get(id));
}
}
Also HttpClient is meant to be used asynchronously, so the MVC controller would also need to be refactored as mixing blocking calls .Result
can cause deadlocks
protected string url = "http://localhost:5001/api/Hospital";
[HttpGet]
public async Task<IActionResult> Edit(int id) {
if (id.Equals(0))
return StatusCode(404);
var accessToken = await HttpContext.GetTokenAsync("access_token");
client.SetBearerToken(accessToken);
HttpResponseMessage responseMessage = await client.GetAsync(url + "/GetById/" + id);
if (responseMessage.IsSuccessStatusCode) {
var responseData = await responseMessage.Content.ReadAsStringAsync();
var hospital = JsonConvert.DeserializeObject<Hospital>(responseData);
var hospitalVM = Mapper.Map<HospitalViewModel>(hospital);
return View(hospitalVM);
}
return View("Error");
}
Upvotes: 4