0

I need help with returning multiple values from my api to the httpclient post request but its returning null

api

[HttpPost("ShowUser")]
    public (IEnumerable<UserInformation>, int) ShowUser([FromBody] Pagination pagination)
    { // retrieving data from database 
        var result = _showUsers.ShowManagerUsers(pagination.PageSize, pagination.skip, pagination.searchValue); // the output here is({System.Collections.Generic.List<Entities.UserInformation>}, 37) (note: 37 is the rows total)
        Entities.PaginationResponse<IEnumerable<UserInformation>> paginationResponse = new Entities.PaginationResponse<IEnumerable<UserInformation>>
        {
            Data = result.Item1,
            RowsCount = result.Item2
        };
        return (paginationResponse.Data, paginationResponse.RowsCount);
    }

HttpClient Post Request

public async Task<(List<TOut>, TOut)> PostGetListRequest<TIn, TOut>(TIn content, string uri, string token)
    {
            ...

            using (response = await client.PostAsync(uri, serialized))
            {
                if (response.StatusCode.ToString() == "OK")
                {
                    responseBody =  response.Content.ReadAsStringAsync().Result;
                    var result = JsonConvert.DeserializeObject<(List<TOut>, TOut)>(responseBody);
                    return (result.Item1, result.Item2);
                }
                  ...
            }
    }

Output enter image description here

enter image description here

Any idea what's wrong with my code?

0

3 Answers 3

1

Try changing your API code to this.

    [HttpPost("ShowUser")]
    public ActionResult ShowUser([FromBody] Pagination pagination)
    { // retrieving data from database 
        var result = _showUsers.ShowManagerUsers(pagination.PageSize, pagination.skip, pagination.searchValue); // the output here is({System.Collections.Generic.List<Entities.UserInformation>}, 37) (note: 37 is the rows total)
        Entities.PaginationResponse<IEnumerable<UserInformation>> paginationResponse = new Entities.PaginationResponse<IEnumerable<UserInformation>>
        {
            Data = result.Item1,
            RowsCount = result.Item2
        };
        return Ok((paginationResponse.Data, paginationResponse.RowsCount));
    }

If this is is designed to be an API that others will consume, you really shouldn't be returning anonymous objects. I think it would be a better idea to either return a wrapper model, or simply return the pagingResponse model you already have.

    [HttpPost("ShowUser")]
    [ProducesResponseType(typeof(Entities.PaginationResponse<IEnumerable<UserInformation>>), StatusCodes.Status200OK)]
    public ActionResult ShowUser([FromBody] Pagination pagination)
    { // retrieving data from database 
        var result = _showUsers.ShowManagerUsers(pagination.PageSize, pagination.skip, pagination.searchValue); // the output here is({System.Collections.Generic.List<Entities.UserInformation>}, 37) (note: 37 is the rows total)
        Entities.PaginationResponse<IEnumerable<UserInformation>> paginationResponse = new Entities.PaginationResponse<IEnumerable<UserInformation>>
        {
            Data = result.Item1,
            RowsCount = result.Item2
        };
        return Ok(paginationResponse);
    }

Let me know if this doesn't work or if you need anything else.

Happy coding!

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for helping me, I tried ur solution it worked but I don't know if there is a way to deserialize two object (data, rowcount)
Hi there. I'm glad it solved your issue. Short answer is no, it's considered bad practice. As I said, the correct approach is to either return the paginationResponse or create a wrapper model. Keep it simple. :) If you really want to return a tuple, you will need to create a custom converter on your API - which would essentially just result in you returning a wrapper model anyway. If you really want to go with this approach, you can read through this example. json converter
0

1-you should await for reading response content

                    responseBody =  await response.Content.ReadAsStringAsync();
2-Make Sure the response in not empty.

3- i discourage using tuples as it violates the Object orinted and clean code practices

1 Comment

I removed await to be able to read the result as (result.item1, result.item2)
0
  1. For the empty response body, if your project version is beyond ASP.NET Core 3.x, be sure add NewtonSoft support, check detailed steps in this answer

    services.AddControllers()
        .AddNewtonsoftJson();
    
  2. Assume that the PostGetListRequest<TIn, TOut> method is invoked by using the following code, TOut is type of UserInformation class:

    await GetListRequest<string, UserInformation>("xxx", "https://localhost:portNumber/xxx", "xxx");
    

    So the deserialize type should be (List<UserInformation>, UserInformation).

    var result = JsonConvert.DeserializeObject<(List<TOut>, TOut)>(responseBody);
    

    But your API's return type is (IEnumerable<UserInformation>, int).

    public (IEnumerable<UserInformation>, int) ShowUser([FromBody] Pagination pagination)
    

    API's return type does not match the deserialize type. So you cannot deserialize successfully.

A working demo:

public async Task<(List<TOut>, int)> GetListRequest<TIn, TOut>(TIn content, string uri, string token)
{
    HttpClient client = new HttpClient();
    var response = await client.PostAsync(uri,serialized);
            
    var responseBody = response.Content.ReadAsStringAsync().Result;
    var result = JsonConvert.DeserializeObject<(List<TOut>, int)>(responseBody);
    return (result.Item1, result.Item2);
}

Api:

[HttpPost("ShowUser")]
public (IEnumerable<UserInformation>, int) ShowUser([FromBody] Pagination pagination)
{ // retrieving data from database 
    var result = _showUsers.ShowManagerUsers(pagination.PageSize, pagination.skip, pagination.searchValue); // the output here is({System.Collections.Generic.List<Entities.UserInformation>}, 37) (note: 37 is the rows total)
    Entities.PaginationResponse<IEnumerable<UserInformation>> paginationResponse = new Entities.PaginationResponse<IEnumerable<UserInformation>>
    {
        Data = result.Item1,
        RowsCount = result.Item2
    };
    return (paginationResponse.Data, paginationResponse.RowsCount);
}

Result:

enter image description here

enter image description here

6 Comments

Thank u @Rena for helping my but I'm still getting a null result
Hi, are you sure your api actually return data? Do you debug your code?
I tested my api in Postman its returning null I don't know why
Hi, you need set breakpoint to your api and debug it step by step to check which line does not contain value... Especially check the result in the ShowUser method. BTW, does the frombody parameter Pagination pagination receives the value?
yes pagination receives values, and result output is (the list and the count) but api return null
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.