Home > Mobile >  HttpReponseMessage returns 404 when making call to api in C#
HttpReponseMessage returns 404 when making call to api in C#

Time:03-09

I am trying to follow these guidelines to make a call to their API and get a prefilled QR code in return.

https://developer.swish.nu/api/qr-codes/v1#pre-filled-qr-code

But I get error 404 not found back, this is my code:

HttpClient client = new HttpClient();
client.BaseAddress = new Uri("https://mpc.getswish.net/qrg-swish");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));

var json = new {
payee = new {value = "1234", editable = false}, 
amount = new {value = 100, editable = false},
message = new {value = "test message", editable = false},
format = "png"
};
HttpResponseMessage response = await client.PostAsJsonAsync(
"/api/v1/prefilled", json);

Does anybody know what I might be doing wrong?

CodePudding user response:

client.BaseAddress = new Uri("https://mpc.getswish.net/qrg-swish");
HttpResponseMessage response = await client.PostAsJsonAsync("/api/v1/prefilled", json);

The problem is the leading / in the path passed to PostAsJsonAsync, and the lack of trailing / in the BaseAddress. Change that to:

client.BaseAddress = new Uri("https://mpc.getswish.net/qrg-swish/");
HttpResponseMessage response = await client.PostAsJsonAsync("api/v1/prefilled", json);

HttpClient combines the path passed to PostAsJsonAsync with the value of HttpClient.BaseAddress by doing new Uri(BaseAddress, path), see here.

If we try this out:

var baseUri = new Uri("https://mpc.getswish.net/qrg-swish");
var result = new Uri(baseUri, "/api/v1/prefilled");
Console.WriteLine(result);

We get the result:

https://mpc.getswish.net/api/v1/prefilled

Looking at the Remarks for new Uri(Uri baseUri, string relativeUri), we see:

If the baseUri has relative parts (like /api), then the relative part must be terminated with a slash, (like /api/), if the relative part of baseUri is to be preserved in the constructed Uri.

Additionally, if the relativeUri begins with a slash, then it will replace any relative part of the baseUri

So in order to preserve the path at the end of BaseAddress, it needs to end in a /, and the path passed to PostAsJsonAsync needs to not start with a /.


With that in place, we get a 400 Bad Request rather than a 404 Not Found. Let's take a look at the response body, and see whether the server is telling us anything useful:

HttpResponseMessage response = await client.PostAsJsonAsync(
            "api/v1/prefilled", json);
Console.WriteLine(response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());

We get:

BadRequest
{"timestamp":"2022-03-09T10:14:45.292 0000","status":400,"error":"Bad Request","message":"Invalid phone number length","path":"/qrg-swish/api/v1/prefilled"}

So, our phone number isn't valid: it's too short. Let's fix that:

payee = new {value = "01234567890", editable = false}, 

Now we get:

BadRequest
{"timestamp":"2022-03-09T10:15:30.675 0000","status":400,"error":"Bad Request","message":"The size parameter is required when using format PNG","path":"/qrg-swish/api/v1/prefilled"}

Right, we need to specify a size. In fairness, the docs do say:

Size of the QR code. The code is a square, so width and height are the same. Not required if the format is svg.

So let's do that:

size = 300,

And there we have it, success!

  • Related