HttpStatus and DownloadData - c#

I'm trying to download a file (an image) with RestSharp using the DownloadData method
var client = new RestClient(baseUrl);
var request = new RestRequest("GetImage", Method.GET);
var response = client.DownloadData(request);
This works fine, but if the requests returns an error I cannot see the HttpStatus code.
I could make a Request and check the status:
var client = new RestClient(baseUrl);
var request = new RestRequest("GetImage", Method.GET);
var response = client.Execute(request);
var status = response.StatusCode;
But then I cannot get the image from the Content property.
I'm I missing something obvious?

The image data would be in RestResponse.RawBytes

Related

How to set "custom" Content-Type of an HttpClient request in DOT NET CORE?

I'm trying to set Content-Type as "application/x.example.hr.employee.email+json;version=1" of an HttpClient request as required by the API I am calling. The API is of type GET and accepts a JSON body (containing list of emails).
I'm successfully able to set Accept header to "application/x.example.hr.employee+json;version=1". In this case, both - Accept and Content-Type need to be set as mentioned, otherwise API throws a error of 400 (Bad request). I tried How do you set the Content-Type header for an HttpClient request? and several other options but getting run time error when I try to set Content-Type other than "application/json".
This type needs to be applied on the request content but not in the header Content-Type. Below is one of the code snippet I tried:
_httpClient.BaseAddress = new Uri("http://example.com/");
_httpClient.DefaultRequestHeaders.Add(HeaderNames.Accept, "application/x.example.hr.employee+json;version=1");
//_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/x.example.hr.employee.email+json;version=1"); // Throws exception
List<string> strEmail = new List<string>
{
employeeEmail
};
var jsonEmail = JsonConvert.SerializeObject(strEmail);
var request = new HttpRequestMessage()
{
Method = HttpMethod.Get,
RequestUri = new Uri("http://example.com/employees"),
Content = new StringContent(jsonEmail, Encoding.UTF8, "application/x.example.hr.employee.email+json;version=1")
};
//var response = _httpClient.SendAsync(request).ConfigureAwait(false);
await _httpClient.SendAsync(request)
.ContinueWith(responseTask =>
{
var response = responseTask;
});
For a reason that don't fully understand, the "application/x.example.hr.employee.email+json;version=1" media type is not correctly parsed whenever you build a StringContent (or actually a MediaTypeHeaderValue).
I did find a workaround for this:
List<string> strEmail = new List<string> {
employeeEmail
};
var jsonEmail = JsonConvert.SerializeObject(strEmail);
var content = new StringContent(jsonEmail, Encoding.UTF8);
content.Headers.ContentType = new MediaTypeHeaderValue("application/x.example.hr.employee.email+json");
content.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("version", "1"));
var request = new HttpRequestMessage()
{
Method = HttpMethod.Get,
RequestUri = new Uri("http://example.com/employees"),
Content = content
};
It's odd that the MediaTypeHeaderValue constructor (which is what StringContent calls) doesn't accept "application/x.example.hr.employee.email+json; version=1".
However, MediaTypeHeaderValue.Parse does.
var contentType = MediaTypeHeaderValue.Parse("application/x.example.hr.employee.email+json; version=1");
var content = new StringContent(jsonEmail, Encoding.UTF8, contentType);
If you're stuck on .NET 6 and below:
var content = new StringContent(jsonEmail, Encoding.UTF8);
content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x.example.hr.employee.email+json; version=1");
See this GitHub issue for a discussion.

Calling Get Request with Json Body using httpclient

I came with an issue this morning where the Api which I am calling is a Get Method but to get Get the Data from it I had to send the json body this is working good when I am testing it in the post man but I am not able to implement it in my project where I am calling this using HttpClient
here is the screenshot of post
It also have a bearer token which I pass in Authorization
Now when I am try to implement this at client side here is my code
var stringPayload = JsonConvert.SerializeObject(json);
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("https://myapiendpoint/serviceability/"),
Content = new StringContent(stringPayload, Encoding.UTF8, "application/json"),
};
var response = await client.SendAsync(request).ConfigureAwait(false);
response.EnsureSuccessStatusCode();
var responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
when I call this method using this code I get
System.Net.HttpStatusCode.MethodNotAllowed - Status code 405
I also tried changing this line
Method = HttpMethod.Get to Method = HttpMethod.Post
but still getting same error
I know this is bad implementation at API Side the request ideally should be POST but changing this is not in my hand and hence need to find the solution
almost search all over and trying all the variant of using GET Method finally the solution which worked for me in this case was this
var client = new HttpClient();
client.BaseAddress = new Uri("https://baseApi/");
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Authorization", string.Format("Bearer {0}", token));
var query = new Dictionary<string, string>
{
["pickup_postcode"] = 400703,
["delivery_postcode"] = 421204,
["cod"] = "0",
["weight"] = 2,
};
var url = "methodurl";
var response = await client.GetAsync(QueryHelpers.AddQueryString(url, query));
var responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
return JsonConvert.DeserializeObject<MyModel>(responseBody);
Got QueryHelpers from Microsoft.AspNetCore.WebUtilities package

Problem calling the prediction endpoint uploading an image using rest sharp for the Microsoft custom vision API cognitive service

I am trying to upload an image to the Microsoft custom vision API prediction endpoint using Restsharp, I am trying to use the AddFile method but I am getting a BadRequest as the result, here is the code I am using
public IRestResponse<PredictionResponse> Predict(string imageFileName)
{
var file = new FileInfo(imageFileName);
var serviceUrl = ConfigurationManager.AppSettings["api.custom-vision.prediction.url.file"];
var serviceKey = ConfigurationManager.AppSettings["api.custom-vision.key"];
var client = new RestClient(serviceUrl);
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/octet-stream");
request.AddHeader("Prediction-Key", serviceKey);
request.AddFile(file.Name, file.FullName);
var response = client.Execute<PredictionResponse>(request);
return response;
}
When I execute the method I am getting the following response back from the service
{
"code": "BadRequestImageFormat",
"message": "Bad Request Image Format, Uri: 1062fe0480714281abe2daf17beb3ac5"
}
After looking for ways in the restsharp documentation to properly upload a file, I came to the solution that it needs to be passed as parameter with an array of bytes with the parameter type of ParameterType.RequestBody
Here is the example of the method that actually works
public IRestResponse<PredictionResponse> Predict(string imageFileName)
{
var file = new FileInfo(imageFileName);
var serviceUrl = ConfigurationManager.AppSettings["api.custom-vision.prediction.url.file"];
var serviceKey = ConfigurationManager.AppSettings["api.custom-vision.key"];
var client = new RestClient(serviceUrl);
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/octet-stream");
request.AddHeader("Prediction-Key", serviceKey);
request.AddParameter("content", File.ReadAllBytes(file.FullName), ParameterType.RequestBody);
var response = client.Execute<PredictionResponse>(request);
return response;
}

why RestSharp Request method Change from POST to GET?

I am using RestSharp to post some data to a url. I am monitoring this operation using fiddler. when I use Simple .net HttpClient with this code:
using (var client = new HttpClient())
{
var values = new Dictionary<string, string> {
{ "par1", "1395/11/29" },
{ "par2", "2" }};
var content = new FormUrlEncodedContent(values);
var response = await client.PostAsync("http://someurl.com/resource", content);
var responseString = await response.Content.ReadAsStringAsync();
}
every thing is good and this return true result. but when i try to use RestSharp with this code:
RestSharp.RestRequest request = new RestSharp.RestRequest("/resource");
request.AddParameter("par1", val, RestSharp.ParameterType.RequestBody);
request.AddParameter("par2", val, RestSharp.ParameterType.RequestBody);
request.AddHeader("Origin", "http://someurl.com");
request.Method = RestSharp.Method.POST;
RestSharp.RestClient client = new RestSharp.RestClient("http://someurl.com");
var response = client.Execute(request);
then fiddler show me the request sent by GET method instead of POST?
I check another time my fiddler and found this issue:
Content-Type: par1
why this is happening for me?
Change your ParameterType argument to GetOrPost and it will work
request.AddParameter("par1", val, RestSharp.ParameterType.GetOrPost);
request.AddParameter("par2", val, RestSharp.ParameterType.GetOrPost);
Initialize Request as POST with JSON.
var client = new RestClient(PreUri);
var request = new RestRequest(Uri, Method.POST) {RequestFormat = DataFormat.Json};
Add object in body
request.AddBody(obj);
Execute
var cancellationTokenSource = new CancellationTokenSource();
var response = await client.ExecuteTaskAsync(request, cancellationTokenSource.Token);
I was stupidly doing mistake to call "client.Get" instead of "client.Post". May be this post helps other.
var client = new RestClient("https://someservice.com");
var request = new RestRequest("/token/", Method.POST, DataFormat.Json).AddJsonBody(SomeObject);
var response = client.Get(request);
I was expecting this code to make POST request. Because i specified it as Method.POST.
But after a few hours, i saw my mistake. Yeas i was specifying the method. But just after i am calling client.Get(request); This changes the metod to GET.
So, the right way to use POST request is like follows:
var client = new RestClient("https://someservice.com");
var request = new RestRequest("/token/", DataFormat.Json).AddJsonBody(SomeObject);
var response = client.Post(request);

Posting form submissions with the KOBO REST API

I'm having a little trouble posting form submissions from C# to a KOBO Server (https://kf.kobotoolbox.org). The response I get is 'Bad Gateway'.
Here's my code:
var client = new RestClient("https://kc.kobotoolbox.org/api/v1/submissions");
//var client = new RestClient("https://kc.kobotoolbox.org/api/v1/forms/{pk}/labels");
client.Authenticator = new HttpBasicAuthenticator("a_user", "alpha9876");
//client.AddDefaultUrlSegment("pk", "31037");
//client.AddDefaultUrlSegment("tags", "tag1, tag2");
// client.AddDefaultUrlSegment("format", "xls");
//client.AddDefaultUrlSegment("url", "https://kc.kobotoolbox.org/api/v1/projects/1");
//client.AddDefaultUrlSegment("owner", "https://kc.kobotoolbox.org/api/v1/users/ona");
//client.AddDefaultUrlSegment("name", "project 1");
//client.AddDefaultUrlSegment("date_created", "2013-07-24T13:37:39Z");
//client.AddDefaultUrlSegment("date_modified", "2013-07-24T13:37:39Z");
var request = new RestRequest(Method.POST);
IRestResponse response = client.Execute(request);
request.AddHeader("header", "xml");
request.Resource = "C:\\Users\\Susan\\Desktop\\xmltest\\form_linkage_parentform.xml";
Could anyone help with a sample snippet of what the C# code for making this POST HTTP request would probably look like? Based on this: https://kc.kobotoolbox.org/api/v1/
Thank you!
I finally managed to do it using CSV files (https://kc.kobotoolbox.org/api/v1/forms) as follows:
var client = new RestClient("https://kc.kobotoolbox.org/api/v1/forms/{pk}/csv_import");
client.Authenticator = new HttpBasicAuthenticator("user_name", "password");
client.AddDefaultUrlSegment("pk", "31045");
string file_path = Server.MapPath("~/myform.csv");
var request = new RestRequest(Method.POST);
request.AddFile("csv_file", file_path);
IRestResponse response = client.Execute(request);

Categories

Resources