I'm currently working on an API that should be adding a client in the database and basically my controller looks like this:
[ApiController]
[Route("api/[controller]")]
[Authorize()]
public class ClientController : ControllerBase
{
private readonly IClientService ClientService;
public ClientController(IClientService clientService)
{
this.ClientService = clientService;
}
[HttpPost("AddClient")]
[Consumes("application/json")]
public async Task<IActionResult> AddClient([FromBody]AddNewClientDTO client)
{
if (ModelState.IsValid)
{
await this.ClientService.AddClient(client);
}
return Ok();
}
}
However this code is not working. I have tried multiple things and the only time it's working is when I change the AddNewClientDTO
to object
or dynamic
.
This API is being called via the Web interface which is a ASP.NET application. When the I fill out the form, the controller is making the API call which is being handled by API Gateway. For the gateway, I'm using Ocelot.
I also have authentication with Auth0, but for it I know it's working as I'm not having issues with the GET
for example. When I was testing to make the call via Postman it's working and the client is being added in the database.
Here is the code that is calling the API:
var jsonModel = JsonConvert.SerializeObject(model);
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Add("authorization", $"Bearer {authenticationProviderKey}");
httpClient.DefaultRequestHeaders.Add("client", jsonModel);
StringContent kpcontent = new StringContent(jsonModel, Encoding.UTF8, "application/json");
var kpresponse = await httpClient.PostAsync("https://localhost:7022/api/Client/AddClient", kpcontent);
}
When I'm using Postman to manually pass the client parameters, I'm getting the AddNewClientDTO
object when calling the API, but when using the web app, it's returning "Error 400 - Bad Request" and the only way I can make it working is when I use dynamic or object.
How can I make the AddClient
method to receive the AddNewClientDTO
object instead of dynamic
? Am I doing something wrong when calling the API?
I assume this is because you have a non nullable property defined in your model that you're not sending with your request.
public class Test
{
// All defined as non nullable and must be provided when calling API
public string Value1 { get; set; }
public object Value2 { get; set; }
public int Value3 { get; set; }
}
// What I think youre doing is creating your object without a required property ie. (missing Value1)
var model = new Test()
{
// We are NOT defining "Value1"
Value2 = new object(),
Value3 = 4
}
var jsonModel = JsonConvert.SerializeObject(model);
using (HttpClient httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
httpClient.DefaultRequestHeaders.Add("authorization", $"Bearer {authenticationProviderKey}");
httpClient.DefaultRequestHeaders.Add("client", jsonModel);
StringContent kpcontent = new StringContent(jsonModel, Encoding.UTF8, "application/json");
var kpresponse = await httpClient.PostAsync("https://localhost:7022/api/Client/AddClient", kpcontent);
}
The above will result in a bad request in kpresponse. If a property can be null (not provided) then define it as such using the "?" after the data type ie.
public class Test
{
public string? Value1 { get; set; }
public object Value2 { get; set; }
public int Value3 { get; set; }
}
Note: You can disable this nullable check by the model validator which is on by default but I wouldn't