Skip to main content
 首页 » 编程设计

c#之使用 HttpClient 通过 GET 连接到 WebApi 时出现 404 错误

2024年02月13日31wayfarer

尝试使用 HttpClient 通过 GET 连接到 WebApi 服务时出现 404 错误。但是,POST 工作没有任何问题。在下面的代码中,我有一个自始至终使用的 CreditCard 类。

这是我的路由配置:

config.Routes.MapHttpRoute( 
    name: "DefaultApi", 
    routeTemplate: "api/{controller}/{id}", 
    defaults: new { id = RouteParameter.Optional } 
); 

这是调用异步操作的代码:

Task task1 = RegisterCard(card, false); 
Task task2 = FetchCard(cardid, false); 

这是我的包含异步操作的代码:

private async Task RegisterCard(CreditCard card, bool runAsync) 
{ 
    try 
    { 
        using (HttpClient client = new HttpClient()) 
        { 
            client.BaseAddress = new Uri("http://localhost:63801/"); 
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
 
            HttpResponseMessage response = runAsync 
                                            ? await client.PostAsJsonAsync("api/card", card) 
                                            : client.PostAsJsonAsync("api/card", card).Result; 
 
            response.EnsureSuccessStatusCode(); 
        } 
    } 
    catch (HttpRequestException ex) 
    { 
        throw new HttpRequestException(ex.Message, ex.InnerException); 
    } 
} 
 
private async Task FetchCard(int cardid, bool runAsync) 
{ 
    CreditCard card = new CreditCard(); 
 
    try 
    { 
        using (HttpClient client = new HttpClient()) 
        { 
            client.BaseAddress = new Uri("http://localhost:63801/"); 
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
 
            HttpResponseMessage response = runAsync 
                                            ? await client.GetAsync("api/card/" + cardid) 
                                            : client.GetAsync("api/card/" + cardid).Result; 
 
            response.EnsureSuccessStatusCode(); 
            } 
        } 
    } 
    catch (HttpRequestException ex) 
    { 
        throw new HttpRequestException(ex.Message, ex.InnerException); 
    } 
} 

这是我的 apiController 代码:

[HttpPost] 
public HttpResponseMessage Register(CreditCard card) 
{ 
    HttpResponseMessage result; 
 
    try 
    { 
        RegisterResponse response = _cardRepository.Register(card); 
 
        result = Request.CreateResponse(HttpStatusCode.Created, response); 
    } 
    catch (Exception ex) 
    { 
        // TODO: add logging 
        result = Request.CreateErrorResponse(HttpStatusCode.BadRequest, "failed to register card"); 
    } 
    finally 
    { 
        // TODO: add audit logging of what attempted and who attempted it 
    } 
 
    return result; 
} 
 
[HttpGet] 
public CreditCard Fetch(int cardid) 
{ 
    CreditCard card = new CreditCard(); 
 
    try 
    { 
        card = _cardRepository.Fetch(cardid); 
    } 
    catch (Exception ex) 
    { 
        // TODO: add logging 
    } 
    finally 
    { 
        // TODO: add audit logging of what attempted and who attempted it 
    } 
 
    return card; 
} 

还有我的 CardRepository 代码:

public RegisterResponse Register(Models.CreditCard card) 
{ 
    using (CreditCardContext ccContext = new CreditCardContext()) 
    { 
        card.MaskedNumber = "XXXXXXXXXXXX" + card.Number.Substring(card.Number.Length - 4, 4); 
        card.Number = Crypto.EncryptData_Aes(card.Number, KeyType.CardNumberKey); 
        card.CardGuid = Guid.NewGuid().ToString(); 
        ccContext.CreditCards.Add(card); 
        ccContext.SaveChanges(); 
    } 
    card.ResetSensitive(); 
 
    RegisterResponse response = new RegisterResponse 
    { 
        IsSuccess = true, 
        Message = "successfully registered card", 
        CreditCard = card 
    }; 
 
    return response; 
} 
 
public CreditCard Fetch(int cardid) // , bool masked 
{ 
    CreditCard card; 
 
    using (CreditCardContext ccContext = new CreditCardContext()) 
    { 
        card = ccContext.CreditCards.SingleOrDefault(x => x.Card_ID == cardid); 
    } 
 
    return card; 
} 

问题:为什么在使用 HttpClient 对象通过 HttpGet 连接到我的 WebApi 服务时会收到 404 错误,但在我使用 HttpPost 时却能正常工作?

请您参考如下方法:

问题是您的 Fetch 方法中的参数命名。

如果根据指定的路由将其更改为 id,它应该可以工作:

[HttpGet] 
public CreditCard Fetch(int id) // , bool masked 
{ 
   ... 
} 

或者,您也可以使用命名参数调用 api(例如 api/card/?cardid=2)