Reputation: 31
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);
}
...
}
}
Any idea what's wrong with my code?
Upvotes: 0
Views: 3290
Reputation: 36695
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();
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:
Upvotes: 0
Reputation: 716
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!
Upvotes: 1
Reputation: 254
1-you should await for reading response content
responseBody = await response.Content.ReadAsStringAsync();
3- i discourage using tuples as it violates the Object orinted and clean code practices
Upvotes: 0