1

I've a endpoint like below in Api 1

[HttpPost]
public ActionResult PostSchoolQuery([FromBody] SchoolQueryModel schoolQueryModel, [FromHeader] string authorization)
{

}

Here the Request Model class like below

public class SchoolQueryModel
{
 public List<Guid?> SchoolIds { get; set; }
 public List<Guid?> DistrictIds { get; set; }
}

And when I try to call the endpoint PostSchoolQuery from Api 2 like below , In api-1 I'm always receiving null values

 public ActionResult GetUserSchools(SchoolQueryModel getSchoolsModel)
        {
           dynamic schoolDetails = null;          
            var requestContent = new JsonSerializer.Serialize(getSchoolsModel);
            using (var client = new HttpClient())
            {
                client.DefaultRequestHeaders.Add("Authorization", _infrastructureAuthKey);
                var responseTask = client.PostAsync("http://localhost:6200/api/post_school_query", requestContent);
                if (responseTask.Result.IsSuccessStatusCode)
                {
                    var readTask = responseTask.Result.Content.ReadAsAsync<JObject>();
                    readTask.Wait();
                    schoolDetails = readTask.Result;
                }
            }
  }

let me know for a fix, Thanks

Rena
  • 30,832
  • 6
  • 37
  • 72
Vasanth R
  • 172
  • 1
  • 1
  • 14

4 Answers4

1

First try to set the Content-Type header to "application/json" when making the request from Api 2:

client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

Then you need to create a StringContent object from the serialized request body, and pass it as the second argument to the PostAsync method. You can do this as follows:

var content = new StringContent(requestContent, Encoding.UTF8, "application/json");
var responseTask = client.PostAsync("http://localhost:6200/api/post_school_query", content);

So your GetUserSchools method should look like:

public ActionResult GetUserSchools(SchoolQueryModel getSchoolsModel)
{
   dynamic schoolDetails = null;          
    var requestContent = new JsonSerializer.Serialize(getSchoolsModel);
    using (var client = new HttpClient())
    {
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        client.DefaultRequestHeaders.Add("Authorization", _infrastructureAuthKey);
        var content = new StringContent(requestContent, Encoding.UTF8, "application/json");
        var responseTask = client.PostAsync("http://localhost:6200/api/post_school_query", content);
        if (responseTask.Result.IsSuccessStatusCode)
        {
            var readTask = responseTask.Result.Content.ReadAsAsync<JObject>();
            readTask.Wait();
            schoolDetails = readTask.Result;
        }
    }
}
godot
  • 3,422
  • 6
  • 25
  • 42
0

Try this one PostAsJsonAsync

public ActionResult GetUserSchools(SchoolQueryModel getSchoolsModel)
{
    dynamic schoolDetails = null;

    using (var client = new HttpClient())
    {
        client.DefaultRequestHeaders.Add("Authorization", _infrastructureAuthKey);
        var responseTask = client.PostAsJsonAsync("http://localhost:6200/api/post_school_query", getSchoolsModel);
        if (responseTask.Result.IsSuccessStatusCode)
        {
            var readTask = responseTask.Result.Content.ReadAsAsync<JObject>();
            readTask.Wait();
            schoolDetails = readTask.Result;
        }
    }
}
Betsq9
  • 135
  • 1
  • 3
  • 11
0

This one works for me. I've also included some better practices:

using System.Text;
using System.Text.Json;
using Microsoft.AspNetCore.Mvc;

namespace AspNetPlayground.Controllers;

[ApiController]
[Route("[controller]/[action]")]
public class TestController : ControllerBase
{
    private readonly HttpClient _httpClient;

    public TestController(IHttpClientFactory httpClientFactory) => _httpClient = httpClientFactory.CreateClient();

    [HttpPost]
    public Task<bool> IsNotNull([FromBody] SchoolQueryModel? schoolQueryModel) => Task.FromResult(schoolQueryModel is not null);

    [HttpPost]
    public async Task<bool> Run()
    {
        var getSchoolsModel = new SchoolQueryModel {SchoolIds = new() {Guid.NewGuid()}, DistrictIds = new() {Guid.NewGuid()}};
        using var requestContent = new StringContent(JsonSerializer.Serialize(getSchoolsModel), Encoding.UTF8, "application/json");
        using var response = await _httpClient.PostAsync("https://localhost:7041/Test/IsNotNull", requestContent);
        return response.IsSuccessStatusCode && await response.Content.ReadFromJsonAsync<bool>();
    }
}

public class SchoolQueryModel
{
    public List<Guid?> SchoolIds { get; init; } = new();
    public List<Guid?> DistrictIds { get; init; } = new();
}
  • actually my problem is different , even if i used async & await and the above best practice .. i'm receiving null values only in target endpoint – Vasanth R Mar 03 '23 at 13:30
  • Please try the solution I posted. It does work for me. I suspect that your solution has some other issue, with authorization for example. – MutedExclamation Mar 03 '23 at 13:43
  • here i'm getting Unable to resolve service for type 'System.Net.Http.IHttpClientFactory – Vasanth R Mar 03 '23 at 16:51
  • In your startup code you have to call `AddHttpClient()` from the `Microsoft.Extensions.DependencyInjection` package. – MutedExclamation Mar 17 '23 at 08:24
0

This fix works for me , I'm not sure why. if anyone knows please comment here

In my api -2 I used JObject instead of a request model and PostAsJsonAsync directly

public ActionResult GetUserSchools(JObject getSchoolsModel)
{
using (var client = new HttpClient())
{
               
var responseTask = await client.PostAsJsonAsync( requestUrl, getSchoolsModel);
                
}

}
Vasanth R
  • 172
  • 1
  • 1
  • 14