Reputation: 12674
I'm trying to create a POST call using HttpClient that I have fully working in Postman. Here is the body I'm sending in Postman:
{
"searchType": "games",
"searchTerms": [
"mario"
],
"searchPage": 1,
"size": 20,
"searchOptions": {
"games": {
"userId": 0,
"platform": "",
"sortCategory": "popular",
"rangeCategory": "main",
"rangeTime": {
"min": 0,
"max": 0
},
"gameplay": {
"perspective": "",
"flow": "",
"genre": ""
},
"modifier": ""
},
"users": {
"sortCategory": "postcount"
},
"filter": "",
"sort": 0,
"randomizer": 0
}
}
I have this written as the following in C#:
var client = _httpClientFactory.CreateClient(HttpClients.HowLongToBeat.ToString());
var request = new HowLongToBeatRequest
{
SearchType = "games",
SearchTerms = searchTerm.Trim().Split(" "),
SearchPage = 1,
Size = 20,
SearchOptions = new SearchOptions
{
Games = new SearchOptionsGames
{
UserId = 0,
Platform = "",
SortCategory = "popular",
RangeCategory = "main",
RangeTime = new SearchOptionsGamesRangeTime
{
Min = 0,
Max = 0
},
Gameplay = new SearchOptionsGamesGameplay
{
Perspective = "",
Flow = "",
Genre = ""
},
Modifier = ""
},
Users = new SearchOptionsUsers
{
SortCategory = "postcount"
},
Filter = "",
Sort = 0,
Randomizer = 0
}
};
//var json = JsonSerializer.Serialize(request);
//var content = new StringContent(json, Encoding.UTF8, "application/json");
//var response = await client.PostAsync("api/search", content);
var response = await client.PostAsJsonAsync("api/search", request, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
});
return new HowLongToBeatResponse();
I have this set up as
The url I'm hitting is: https://www.howlongtobeat.com/api/search
and I'm setting it up like so in my Startup.cs
services.AddHttpClient(HttpClients.HowLongToBeat.ToString(), config =>
{
config.BaseAddress = new Uri("https://www.howlongtobeat.com/");
config.DefaultRequestHeaders.Add("Referer", "https://www.howlongtobeat.com/");
});
I am passing this Referer header in my Postman collection as well.
Basically, I can't figure out why this code gets a 403 in C# but the Postman that I think is exactly the same is getting a successful response. Am I missing something?
Let me know if there's any missing info I can provide.
Upvotes: 4
Views: 1884
Reputation: 1
I know this has already been resolved but in case anyone needed any pointers for making requests to HLTB API:
As the author mentioned
The issue was that this specific API required a User Agent header specified.
However, as of June 2023 (quite possibly prior to that), to make calls to 'https://www.howlongtobeat.com/api/search' you need to have also set Header's:
As For the body, you do not need to include the entire json as shown in the author's example, this is enough:
{"searchTerms":["The", "Witcher", "3"]}
For C# specifically, make sure there is no encoding on your StringContent (used for the request's body) and is of a type of 'application/json'.
Upvotes: 0
Reputation: 12674
I solved my problem. The issue was that this specific API required a User Agent header specified.
Upvotes: 2
Reputation: 5862
I think the problem is here, The BaseAddress property needs to be suffixed (https://www.howlongtobeat.com/) with a forward slash and here you already set route as well, change it to
services.AddHttpClient(HttpClients.HowLongToBeat.ToString(), config =>
{
config.BaseAddress = new Uri("https://www.howlongtobeat.com/");
config.DefaultRequestHeaders.Add("Referer", "https://www.howlongtobeat.com/api/search");
});
And then
var response = await client.PostAsJsonAsync("api/search", request, new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
});
Updated:
try this, here I have hard-coded the Base URL for testing purposes.
try
{
var data_ = JsonConvert.SerializeObject(root);
var buffer_ = System.Text.Encoding.UTF8.GetBytes(data_);
var byteContent_ = new ByteArrayContent(buffer_);
byteContent_.Headers.ContentType = new MediaTypeHeaderValue("application/json");
string _urls = "https://www.howlongtobeat.com/api/search";
var responses_ = await _httpClient.PostAsJsonAsync(_urls, byteContent_);
if (responses_.StatusCode == HttpStatusCode.OK)
{
Console.WriteLine("[GetPrimeryAccount] Response: Success");
string body = await responses_.Content.ReadAsStringAsync();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message); ;
}
Upvotes: 0