简体   繁体   English

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

[英]404 Error when using HttpClient to connect to WebApi with GET

I'm getting a 404 error when trying to use an HttpClient to connect to a WebApi service using GET. 尝试使用HttpClient通过GET连接到WebApi服务时,出现404错误。 However, POST works without any problem. 但是,POST可以正常工作。 In the code below, I have a CreditCard class that I use throughout. 在下面的代码中,我使用了一个CreditCard类。

Here's my routing configuration: 这是我的路由配置:

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

Here's my code that calls the async operation: 这是调用异步操作的代码:

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

Here's my code that contains the the async operations: 这是我的代码,其中包含异步操作:

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

Here's my code for the apiController: 这是我的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;
}

And my code for the CardRepository: 还有我的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;
}

QUESTION: Why am I getting a 404 error when using an HttpClient object to connect to my WebApi service using HttpGet, but when I use HttpPost, it works correctly? 问题:为什么当使用HttpClient对象使用HttpGet连接到WebApi服务时出现404错误,但是当我使用HttpPost时,它可以正常工作吗?

The problem is the parameter naming in your Fetch method. 问题是您的Fetch方法中的参数命名。

If you change it to id as per the route specified it should work: 如果您按照指定的路线将其更改为id ,则它应该可以工作:

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

Or, alternatively, you could call the api with the named param (eg api/card/?cardid=2 ) 或者,您也可以使用已命名的参数调用api(例如api/card/?cardid=2

In Web API 2 you can use Attribute Routing 在Web API 2中,您可以使用属性路由

[Route("api/card/{cardid:int}")]
[HttpGet]
public CreditCard Fetch(int cardid)
{
    ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM