C
C#3y ago
sonodan.

Http 400 Bad Request Response [Answered]

POST controller in WebAPI.
[Route("api/[controller]")]
[ApiController]
public class EventsController : ControllerBase
{
[HttpPost]
public async Task UpdateContacts(List<EventModel> events)
{
// Do things here

}
}
[Route("api/[controller]")]
[ApiController]
public class EventsController : ControllerBase
{
[HttpPost]
public async Task UpdateContacts(List<EventModel> events)
{
// Do things here

}
}
Service from the client that calls the Web API:
public async Task UpdateEvents(int userId, List<EventModel> events)
{
var contractResolver = new DefaultContractResolver()
{
NamingStrategy = new CamelCaseNamingStrategy()
};

var json = JsonConvert.SerializeObject(events, new JsonSerializerSettings
{
ContractResolver = contractResolver,
Formatting = Formatting.Indented
});

_httpClient.DefaultRequestHeaders.Clear();
_httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

var result = await _httpClient.PostAsJsonAsync($"api/events", json);
}
public async Task UpdateEvents(int userId, List<EventModel> events)
{
var contractResolver = new DefaultContractResolver()
{
NamingStrategy = new CamelCaseNamingStrategy()
};

var json = JsonConvert.SerializeObject(events, new JsonSerializerSettings
{
ContractResolver = contractResolver,
Formatting = Formatting.Indented
});

_httpClient.DefaultRequestHeaders.Clear();
_httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));

var result = await _httpClient.PostAsJsonAsync($"api/events", json);
}
I've tried many things, including serializing the object to Json using Newtonsoft and just passing the object in for the HttpClient to serialize. I keep getting a 400 bad request response, and the content doesn't seem to provide any insight as to why that is. Note that I have provided the correct base URL to the httpClient as it works for my GET requests.
47 Replies
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
sonodan.
sonodan.OP3y ago
Thanks - I actually just added that temporarily to see if it fixes my issue, but I will insure to do it only on instantiating the HttpClient 🙂
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
sonodan.
sonodan.OP3y ago
Ok, so I've simplified my service to just call:
public async Task UpdateEvents(int userId, List<EventModel> events)
{
var result = await _httpClient.PostAsJsonAsync($"api/events", events);
}
public async Task UpdateEvents(int userId, List<EventModel> events)
{
var result = await _httpClient.PostAsJsonAsync($"api/events", events);
}
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
sonodan.
sonodan.OP3y ago
It still returns a 400 bad request. is there a way to see the body of the request? I have inspected the result object but can't see the json output. Could it perhaps be an issue of not using json with camelCase, which is what the API expects?
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
sonodan.
sonodan.OP3y ago
this is just a personal project, so i'm writing the front-end and back-end for this
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
sonodan.
sonodan.OP3y ago
I linked the controller code that's being calledin the OP. It doesn't actually have any logic in yet, so I am just trying to see that I get a 200 return code from it
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
sonodan.
sonodan.OP3y ago
The EventModel?
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
sonodan.
sonodan.OP3y ago
public class EventModel
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime Date { get; set; }
public string Location { get; set; }
public IEnumerable<FightModel> Fights { get; set; }
}
public class EventModel
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime Date { get; set; }
public string Location { get; set; }
public IEnumerable<FightModel> Fights { get; set; }
}
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
sonodan.
sonodan.OP3y ago
I updated to this:
[HttpPost]
public async Task<ActionResult> UpdateContacts(List<EventModel> events)
{
// Do things here
Console.WriteLine("Called Api");

return Ok();
}
[HttpPost]
public async Task<ActionResult> UpdateContacts(List<EventModel> events)
{
// Do things here
Console.WriteLine("Called Api");

return Ok();
}
Still returned a 400
Pobiega
Pobiega3y ago
have you set a base url for your httpclient? since the url you are giving it is just api/events
sonodan.
sonodan.OP3y ago
yep, and i'm confident that is correct because I have a GET method in my API that works ]using the same httpclient
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
sonodan.
sonodan.OP3y ago
thanks for posting this - I explicity typed in my URL as you did to still no avail. Apart from that I don't see any differences in our implementation, which is really strange. I'll have to have another crack at it after work Thanks so much for your time!
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Pobiega
Pobiega3y ago
wait what you registerered the controller as a typed client, and it never hit the ctor?
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Pobiega
Pobiega3y ago
Yeah I was like "no way you can register a controller as a typed client" :p
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Pobiega
Pobiega3y ago
yea weird
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
sonodan.
sonodan.OP3y ago
@tebeco Would there be some sort of security setting by default in web API to prevent me from calling a PUT/POST method but allowing me to call GET?
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
sonodan.
sonodan.OP3y ago
@tebeco I noticed something interesting - when I remove the eventModel from being passed, and just pass through an int to the httpClient call the request works. So you're right, it must be a serialization issue. I notice you use a record as opposed to a class - is there something in the way these are serialized differently? Yeah, hang on a sec and I can DM you a link ok sent - the controllers are obviously in the API proj, and the part calling the controller is in Client proj under services. Calling this service is bound to the 'Save' button on the UI
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
sonodan.
sonodan.OP3y ago
I just removed this dependency. It actually wasn't loaded in properly (had a warning) so I don't think it was actively being used
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
sonodan.
sonodan.OP3y ago
Honestly, I followed the structure used in a TimCorey web api tutorial to get me started. Are these considered bad practices? Yeah it's dapper
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
sonodan.
sonodan.OP3y ago
I want to learn best practices tbh - I can switch it to EF and not use stored procs if that's more common It's only a practice personal proj so it's for learning
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
sonodan.
sonodan.OP3y ago
ok, will research what dapper recommends and check that. I think it's dynamic because it's used for parameters, which I guess can hold a variety of diff data?
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
sonodan.
sonodan.OP3y ago
ah shit I was supposed to remove minimalApi proj - i'm not actually using that i was playing with it im using MmaPredictionsAPI which uses controllers instead MmaPredictions.Client MmaPredictions.Shared MmaPredictionsAPI are the 3 projs - i should have tidied that before sending you to repo sorry
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
sonodan.
sonodan.OP3y ago
I was using newtonsoft to originally serialize the object into JSON for the HttpClient transport - but then you explained that the point of 'PostAsAsync' is that is deserializes for you, so I removed that part of the code but forgot to remove packrefernece sorry 'PostAsJsonAsync'
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
MODiX
MODiX3y ago
tebeco#0205
builder.Services.AddTransient<FooClient>();
builder.Services.AddHttpClient<FooClient>(httpClient =>
{
httpClient.BaseAddress = new Uri("http://localhost:5179/", UriKind.Absolute);
httpClient.DefaultRequestHeaders.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
});
builder.Services.AddTransient<FooClient>();
builder.Services.AddHttpClient<FooClient>(httpClient =>
{
httpClient.BaseAddress = new Uri("http://localhost:5179/", UriKind.Absolute);
httpClient.DefaultRequestHeaders.Clear();
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
});
Quoted by
React with ❌ to remove this embed.
sonodan.
sonodan.OP3y ago
yeah and i tried instantiating it the same way you did locally, but it didnt change anything so i didnt push any changes to git i replicated an eventmodel as a record as you did, without any properties that are custom classes, and it serializes and gives a 200 response -- so I figure this issue is somehow related to either me using a value type instead of reference, or the fact i've got classes that have custom properties? I will update my code in general to follow the practices you showed in yours
Unknown User
Unknown User3y ago
Message Not Public
Sign In & Join Server To View
Accord
Accord3y ago
✅ This post has been marked as answered!
Want results from more Discord servers?
Add your server