【问题标题】:HttpClient call to web api method with integer parameter Returns error 404HttpClient 使用整数参数调用 Web api 方法返回错误 404
【发布时间】:2018-07-07 17:13:03
【问题描述】:

我真的看不出我在这里做错了什么。我正在尝试调用一个通过HttpClient 接受整数的asp.net 核心web api 方法,但它返回404 错误。

HospitalController(网络 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");
}

我在 MVC 中的同一控制器中有一个有效的 POST 方法。但是这个 GET 方法返回 404,我似乎不知道为什么。

【问题讨论】:

    标签: c# asp.net-core asp.net-core-mvc asp.net-core-webapi asp.net-core-routing


    【解决方案1】:

    根据api中有两个路由模板使用

    [HttpGet("{id}")] //Matches GET api/Hospital/5
    [Route("GetById")] //Matches GET api/Hospital/GetById
    

    两者都不匹配

    http://localhost:5001/api/Hospital/GetById/5
    

    Http{Verb} 属性通常用于 RestFul API。

    在构建 REST API 时,您很少会希望在操作方法上使用 [Route(...)]。最好使用更具体的 Http*Verb*Attributes 来准确了解您的 API 支持什么。 REST API 的客户端应该知道哪些路径和 HTTP 动词映射到特定的逻辑操作。

    参考Routing to Controller Actions

    更新 web api 上的路由模板以映射到所需的路由

    [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));
        }
    }
    

    HttpClient 也意味着异步使用,因此 MVC 控制器也需要重构,因为混合阻塞调用 .Result 会导致死锁

    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");
    }
    

    【讨论】:

    • 非常感谢您的深刻见解。它工作得很好。但是快速的问题,假设我有一个接受多个参数(如 int 和 string)的 api 方法,我该如何编写该方法的 HttpGet 属性?我会将您的答案标记为正确,但我需要第二个问题的帮助。谢谢。
    • @KaceyEzerioha,这取决于您希望网址的外观。我的答案中包含的链接指向有关如何进行属性路由的官方文档,包括路由模板和路由约束。您可以有多个不同类型的参数。
    • 非常感谢
    猜你喜欢
    • 2013-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-27
    • 2014-08-07
    • 1970-01-01
    相关资源
    最近更新 更多