HttpClient and REST (Getflix API) - c#

I'm stumped here and hoping for some help. I'll paste in the relevant section of the Getflix API (https://getflix.zendesk.com/hc/en-gb/articles/201689644-API-Resource-Regions):
POST v1/regions.json
Updates the region for a specified service. Only 1 service can be updated at a time, and the following JSON object must be present in the POST body.
{"service": < serviceName >,"region": < regionCode >}
serviceName: is a valid service name (see region list below)
regionCode: is the ISO 2 letter country code for the region to switch to (in upper-case).
Example Usage
curl -u <api_key>:x -X POST -d '{"service":"netflix","region":"US"}' https://www.getflix.com.au/api/v1/regions.json
And here is my code:
string response = await theHandler.POSTreq("https://www.getflix.com.au/api/v1/regions/list.json", "{\"service\":\"netflix\",\"region\":\"US\"}");
and here is theHandler.POSTreq:
public async Task<string> POSTreq(string requestURL, string sendJson)
{
//set credentials
HttpClientHandler handler = new HttpClientHandler();
handler.Credentials = new NetworkCredential(apiKey, "x");
Uri requestUri = new Uri(requestURL);
var objClint = new HttpClient(handler);
HttpResponseMessage respon = await objClint.PostAsync(requestUri, new StringContent(sendJson, System.Text.Encoding.UTF8, "application/json"));
string responJsonText = await respon.Content.ReadAsStringAsync();
return responJsonText;
}
As far as I can figure out, this SHOULD work. it doesn't. The response text I end up getting isn't an error but a whole bunch of HTML.
Anyone know what I'm doing wrong? I've spent hours on this and I'm stumped. ha

Yes, I'm an idiot. I was using the wrong URL. lol.

Related

Sending custom Content-Type using HttpClient C# .Net6

Hello Stackoverflow community. I hope someone here can help me!!
I'm trying to integrate with the Zoopla API that requires the post request to send the following customized content type. (I've got the certificate side of things working fine).
application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json
I've tried the following approaches without any success (they all result in the following error)
System.FormatException: 'The format of value 'application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json' is invalid.'
Initial approach was to set it within the content of the RequestMessage
var request = new HttpRequestMessage()
{
RequestUri = new Uri("https://realtime-listings-api.webservices.zpg.co.uk/sandbox/v1/listing/list"),
Method = HttpMethod.Post,
Content = new StringContent(jsonBody, Encoding.UTF8, "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json")
};
When that didn't work I tried to set it via the default headers (the client below is from the ClientFactory)
client.DefaultRequestHeaders.Add("Content-Type", "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json");
My final attempt was to set it without validation
client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json");
I've just tried something else which unfortunately didn't work
string header = "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json";
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue(header));
I am well and truly stumped!! HELP!! :-)
Content-Type is set on the content, not in DefaultRequestHeaders. You may try using TryAddWithoutValidation on the request content:
var content = new StringContent("hello");
content.Headers.ContentType = null; // zero out default content type
content.Headers.TryAddWithoutValidation("Content-Type", "application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json");
var client = new HttpClient(); // note: use IHttpClientFactory in non-example code
var response = await client.PostAsync("https://postman-echo.com/post", content);
Console.WriteLine(response.StatusCode); // OK
Console.WriteLine(await response.Content.ReadAsStringAsync());
// {"args":{},"data":{},"files":{},"form":{},"headers":{"x-forwarded-proto":"https","x-forwarded-port":"443","host":"postman-echo.com","x-amzn-trace-id":"Root=1-6345b568-22cc353761f361483f2c3157","content-length":"5","content-type":"application/json;profile=http://realtime-listings.webservices.zpg.co.uk/docs/v1.2/schemas/listing/list.json"},"json":null,"url":"https://postman-echo.com/post"}

'UTF8' is not a supported encoding name

So I'm just playing around with Spotify's Web API and I'm trying to access my top played tracks. Although I've encountered a problem I've been trying to solve for a couple of hours now but I can't find an answer.
When I try to deserialize my response, I get the follwing error:
'UTF8' is not a supported encoding name. For information on defining a custom encoding, see the documentation for the Encoding.RegisterProvider method.
Parameter name: name
The character set provided in ContentType is invalid. Cannot read content as string using an invalid character set.
The ContentType is application/json; charset=UTF8
Any ideas?
Here's my request code:
private static HttpClient GetHttpClient()
{
HttpClientHandler handler = new HttpClientHandler() {
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
};
var httpClient = new HttpClient(handler);
httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
return httpClient;
}
public async Task<SearchArtistResponse> GetSelfTopAsync(string type, string userName)
{
var httpClient = GetHttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", GetAccessToken(userName));
var sb = new StringBuilder();
sb.Append(ApiUrl);
sb.Append($"/me/top/{type}");
var query = sb.ToString();
var response = await httpClient.GetAsync(query);
var spotifyResponse = JsonConvert.DeserializeObject<SearchArtistResponse>(await response.Content.ReadAsStringAsync());
return spotifyResponse;
}
Are you using .net core?
You will need to add the following code to make the encodings available in .NET desktop available in your environment:
System.Text.EncodingProvider provider = System.Text.CodePagesEncodingProvider.Instance;
Encoding.RegisterProvider(provider);
More info on CodePagesEncodingProvider.Instance can be found here.
The problem should be a validation of response header Content-Type ,that occur when you call ReadAsStringAsync(), if you call ReadAsByteArrayAsync() instead and parse to string
(System.Text.Encoding.UTF8.GetString())
that will gonna work!!!
I had a same problem while I was trying to get an answer from my API which is built in PHP using C# service. I could fix the issue by changing "charset=UTF8" to "charset=\"UTF-8\"" on the PHP side(the api that sends result to the C# service). Hope this helps someone.

Setting up a REST Client Application (Post) from a Web API

I've been having a few issues in trying to retrieve the results of a POST operation from a Web Service.
I have been using a chrome extension to test the API Services and they are working there. However I've been having problems on implementing it in code.
This is an example of usage of the chrome extension:
What I'm trying to retrieve on code, is the last part, the json array that the POST operation generates, where it says accessToken.
However, in the code that I've been using below, I've only had access to the status (200 OK) etc.
Here's a preview of the code I am using:
{
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(url.Text);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(header.Text));
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, url.Text);
request.Content = new StringContent(body.Text, Encoding.UTF8, header.Text);
client.SendAsync(request)
.ContinueWith(responseTask =>
{
MessageBox.Show(responseTask.Result.Content.Headers.ToString());
}
);
}
The Header.Text is exactly "application/json", the body.Text is body which has those various properties such as username and password (in string format) and url.Text contains the complete URL to call the Web service.
I'd like to know what I'm doing wrong with my code, and what can I do to obtain that json array that contains the accessToken
In your code you need to use ReadAsStringAsync method to convert your HttpContent object to string/json. For example:
client.SendAsync(request)
.ContinueWith(responseTask =>
{
var jsonString = responseTask.Result.Content.ReadAsStringAsync().Result;
MessageBox.Show(jsonString);
});
then you can convert you jsonString as you need.

Softlayer Object Storage ETag MD5 Checksum Calculation

I'm trying to figure out how to calculate the correct checksum when passing data to the Softlayer Object Storage.
I know the ETag is the issue because if I remove it form the request it works, however I'd prefer to use it to verify the uploads are not corrupt.
This is my method:
public bool SaveFile(byte[] file, eFetchStorageContainers container, string internalFileName, string fileName = "", bool overPublicNetwork = false)
{
Authenticate(overPublicNetwork);
client = new RestClient(storage_url);
var resourcePath = string.Format("/{0}/{1}", container, internalFileName);
var req = new RestRequest(resourcePath, RestSharp.Method.PUT);
req.AddHeader("X-Auth-Token", auth_token);
req.AddFile(internalFileName, file, fileName);
var md5Checksum = BitConverter.ToString(MD5.Create().ComputeHash(file)).Replace("-", string.Empty).ToLower();
req.AddHeader("ETag", md5Checksum);
var resp = client.Execute(req);
return false;
}
Here is how the ETag is defined:
I believe the problem lies in the fact that i'm getting the checksum for the file and not the request body.
I want to verify that I should be getting the checksum of the Request Body and NOT the file alone.
If the above is true I'm not even sure how to get the checksum for the body - would love some guidance...
Well I did not use C#, but it works using curl fine for me. I get the checksum for the file and it is working fine.
just in case here some examples about this https://community.runabove.com/kb/en/object-storage/how-to-check-file-consistency-using-etag-and-md5.html
Make sure that your request is similar to examples of the link above.
This is the curl I used:
curl -X PUT -T "C:\Users\ncabero\Downloads\picture.jpg" -H "X-Auth-Token: AUTH_XXXXXXX" -H "Etag: a43bf68dd35599a7873c12128f71b1f4" https://dal05.objectstorage.softlayer.net/v1/AUTH_d684780d-aafe-4772-bcbb-0f07d5f6edf3/rcvtest/picture.jpg
I actually figured this out, I was using RestSharp however its impossible to get the request body.
I moved over to HttpClient and was able to access the request body to create a checksum.
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("X-Auth-Token", auth_token);
var bytes = new ByteArrayContent(file);
var formData = new MultipartFormDataContent();
formData.Add(bytes, internalFileName, internalFileName);
// this creates a checksum to send over for verification of non corrupted transfers
// this is also prevents us from using RestSharp due to its inability to create a checksum of the request body prior to sending
var md5Checksum = BitConverter.ToString(MD5.Create().ComputeHash(formData.ReadAsByteArrayAsync().Result)).Replace("-", string.Empty).ToLower();
httpClient.DefaultRequestHeaders.Add("ETag", md5Checksum);
var url = string.Format("{0}/{1}{2}/{3}", storage_url, containerName, folderId, internalFileName);
var resp = httpClient.PutAsync(url, formData).Result;
httpClient.Dispose();

Trouble with HTTP post in Android

I am fairly new at android development. Here is my problem:
I have this endpoint: http://bdzservice.apphb.com/api/Image which accepts POST requests
The body of the request is a String, example:
/SearchServlet?action=showMap&id1=25&date=09/12/2013&st1=5216000&st2=5229030
Invalid example: {"/SearchServlet?action=showMap&id1=25&date=09/12/2013&st1=5216000&st2=5229030"}
Invalid example2: {mapHref : "/SearchServlet?action=showMap&id1=25&date=09/12/2013&st1=5216000&st2=5229030"}
Invalid example3: {"mapHref" : "/SearchServlet?action=showMap&id1=25&date=09/12/2013&st1=5216000&st2=5229030"}
this is the code I've written so far:
HttpClient client = new DefaultHttpClient();
String message;
HttpPost httpPost = new HttpPost("http://bdzservice.apphb.com/api/Image");
try
{
message = url;
StringEntity se = new StringEntity(message, "UTF8");
se.setContentType("application/json");
httpPost.setEntity(se);
httpPost.setHeader("Content-type", "application/json");
HttpResponse resp = client.execute(httpPost);
if (resp != null)
{
if (resp.getStatusLine().getStatusCode() == 204)
result = true;
}
Log.d("Status line", "" + resp.getStatusLine().getStatusCode());
}
I always get an error when trying to post data, but when I manually (through a REST client) post data I get an OK result.
Can someone help me with this?
EDIT
This is the endpoint, It is written in C# (Web Api)
EDIT 2: Tried modifying the service to return body it recieved (see the comment in the url) and it retruns null, so the problem is it is not getting the body (or just reading it wrong)
I have created a library here for .NET Standard that does POST and PUT. I have tested it thoroughly on Android. There are quick start samples to get going quickly. The sample only has a PUT, but the principle should be the same:
https://bitbucket.org/MelbourneDeveloper/restclient-.net/overview

Categories

Resources