C#: RestClient: RestRequest fails for lower case header - c#

I have the code below in c#, which uses RestClient. The issue is that the headers should not be case-sensitive but looks like they are.
var client = new RestClient(sMA_URL);
var request = new RestRequest(Method.GET);
request.AddHeader("cache-control", "no-cache");
//Without the line below the RestRequest adds some default header which is not acceptable by our server.
request.AddHeader("**Accept**", "*/*");
request.AddHeader("content-type", "application/json");
request.AddHeader("authorization", "Bearer "+sBearerToken);
// Make sure you deserialize this response, for further use. The best way to do this is to create a class and then fill that with the values obtained by the response but if a response is not used many times,
// you can do it the way it has been done in Bearer Token Generation
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
Console.ReadKey();
When I give accept (in lower case) it complains about the content-type but Accept (upper case) works fine.No, error regarding the content-type. I can't figure out if the issue is with the service it's trying to call or with RestClient itself.
This is the status code I get (No exception)
'NotAcceptable Content-Type'

Well the answer is included in the response, its self explanatory.
"NotAcceptable Content-Type"
The message above means that the api, service or endpoint your are trying sending your request to, rejects your request based on the content-type header which is 'application/json'.
Since you are sending a GET request, i don't see why do you need to specify content-type at all.
Try removing the content-type header and probably your request will work.
Adding the content-type header would be used for POST or PUT requests, where you are sending a body/payload in the request (example: json,form data,xml,multipart,etc...), and even for this type of requests it is still not mandatory unless the server you are sending your requests to requires you to specify the content-type.

Related

C# RestSharp No Response From Get With Json Body

My goal is to download a file with a RestSharp GET by passing along a Json body and a security token in the header. For now, I'm just trying to get a response.
I got this code from Postman, where the GET is working (I am prompted where to save the file).
var client = new RestClient(url);
client.Timeout = -1;
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", token);
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", json, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
string responseMsg = "";
if (response.Content == "")
responseMsg = response.ErrorMessage
else
responseMsg = response.Content
return responseMsg;
The only response that I'm getting is the ErrorException "HTTP verb GET does not support body".
So I believe there is an issue with my logic, not my Json or token. Does anything in my code look incorrect?
Application framework: .Net 4.8
RestSharp version: 106.15.0
Thanks.
Edit:
As mentioned below, a GET request with a body parameter is invalid. After removing the the json body, the request is now working.
var client = new RestClient(url);
client.Timeout = -1;
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", token);
IRestResponse response = client.Execute(request);
In the case of my application, the unique identifier was appended to the endpoint, so only the security token was needed as a header.
GET requests cannot have bodies, or rather, they can, but that behaviour is not defined and so some implementations will reject the request entirely. It appears that RestSharp also intentionally does not support GET requests with bodies for the same reason. According to that thread, .NET itself may support them, so you might wish to try that if it's absolutely necessary.
Whether or not you should do that might come under the umbrella of personal opinion, however with that in mind I would caution against doing things outside of the specification, because any updates to libraries or frameworks have no guarantee of consistency of behaviour when they're being used out of spec. If this is an API you have control over, you should consider bringing it in-spec. If it's not, you should consider contacting the developer to have them look into it.

Is there a way to delete a header of a request using RestSharp

I am creating a two test case one of them validates the OK message in response with valid Authentication token and the other validates Unauthorized message with the invalid/missing token.
In first test case the valid Authentication token is provided (as header) which passes the test case. But when I created second test case with missing token it still got passed even though I did not provide any token there. How it is getting passed without the token.
I have already tried request.AddorUpdateParameter, it did not work.
Test Case I
RestClient client = new RestClient(clientName);
RestRequest request = new RestRequest("Products", Method.GET);
request.AddParameter(Common.AuthenticationKey, Common.AuthenticationValue);
IRestResponse response = client.Execute(request);
Test Case II
RestClient client = new RestClient(clientName);
RestRequest request = new RestRequest("Products", Method.GET);
IRestResponse response = client.Execute(request);
It still gives me OK status. It is taking reference of the first test case request?
The second test case should fail since authentication token is not provided.
Adding your own header should overwrite any existing headers, so adding "Accept","*" or something similar should do the trick

HTTP Request works in postman but doesn't work in code

I'm trying to access a website that requires login via a form.
I used the Postman HTTP client.
I tried to do the normally http post request but didn't seem to work, I get a successful status code (200 OK) but it doesn't log in, eventually did work with a GET request with BODY parameters (I hadn't seen GET request with body parameters).
Well, I tried to simulate this request in C# code with no luck, I even tried the generated code that Postman offers with no luck again.
Down below is the Postman request and the C# code snippet based on auto-generated Postman code. Does anyone know if is there to make this request with any library or if there is something that I miss?
Thank you in advance.
var client = new RestClient("https://thessalia-3.teilar.gr/login.asp");
var request = new RestRequest(Method.GET);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddHeader("Referer", "https://thessalia-3.teilar.gr/login.asp");
var parameters = new Dictionary<string, string>();
parameters["userName"] = JsonConvert.SerializeObject("myusername");
parameters["pwd"] = JsonConvert.SerializeObject("mypass");
parameters["loginTrue"] = JsonConvert.SerializeObject("extravalue");
var content = new FormUrlEncodedContent(parameters);
request.AddParameter("application/x-www-form-urlencoded", content);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
Console.WriteLine(response.StatusCode);
Postman Request Photo
Edit:
Postman Request Body Parameters
I've also tried to run this but also not logged in.
Auto-generated code form Postman
If the request was successful (200) and you got the HTML page for "Invalid Credentials", then your code that's making the request should be fine and the issue is with the credentials. Like I said in my first comment, don't serialize the parameters to JSON, URL-encode them instead:
parameters["userName"] = HttpUtility.UrlEncode("myusername");
parameters["pwd"] = HttpUtility.UrlEncode("mypass");
parameters["loginTrue"] = HttpUtility.UrlEncode("extravalue");
This is the standard way and it works with writing the parameters directly to the request stream, or with a utility class like StringContent. However, since you're using the utility class FormUrlEncodedContent, it URL-encode them for you, so you don't have to. In that case, simply assign them directly as string:
parameters["userName"] = "myusername";
parameters["pwd"] = "mypass";
parameters["loginTrue"] = "extravalue";

Removing Content-Type header in .NET Core

I have the following code in .Net Core:
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "Bearer " + _accessToken);
client.DefaultRequestHeaders.TryAddWithoutValidation("Dropbox-API-Arg", GenerateJsonFromObject(new {path = filePath}));
var request = new HttpRequestMessage(HttpMethod.Post, "https://content.dropboxapi.com/2/files/download");
var result = client.SendAsync(request).Result;
}
As you can see it's quite simple piece of code and it works correctly, but only on Windows.
When I'm running the same code on my Linux VPS (Ubuntu 16.04 server with .Net Core 1.0.4) I'm receiving the following error message from Dropbox API:
Error in call to API function "files/download": You provided a non-empty HTTP "Content-Type" header ("application/x-www-form-urlencoded"). This API function requires that the header be missing or empty.
So API requires empty or null Content-Type Header, but somehow in .Net Core this header is automatically added to my request.
The result of printing request headers is the same on Windows and on Linux:
Method: POST, RequestUri: 'https://content.dropboxapi.com/2/files/download', Version: 1.1, Content: <null>, Headers:
{
Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Dropbox-API-Arg: {"path":"/tracklogs/night_ride.gpx"}
}
So my question is:
How to avoid adding Content-Type header automatically by .Net Core?
What I've tried:
1 Set an empty Content-Type header:
client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "");
Won't work, even if I set value of header to "application/json" it's automatically changed to application/x-www-form-urlencoded :(
2 Remove whole header:
request.Headers.Remove("Content-Type");
or:
client.DefaultRequestHeaders.Remove("Content-Type");
In both cases I'm receiving the following exception:
Misused header name. Make sure request headers are used with HttpRequestMessage, response headers with HttpResponseMessage, and content headers with HttpContent objects.'
You are doing a POST. This adds a default content-type for the normally required body.
It's not clear if the specification mandates a body but this the point of a POST over a GET, and is sometimes implemented as required (although of course it might be a blank). In view of this, I suspect .net always adds a content-type header to give that body meaning. https://www.rfc-editor.org/rfc/rfc9110.html#name-method-definitions
Possibly this request should be a GET which doesn't require a body. There may also be alternative ways to make the request which give more control over the construction of the request.

RestSharp no response when Transfer-Encoding: chunked

I am trying to use a very simple RestSharp client like this
RestClient client = new RestClient(#"http://hostname:28000");
RestRequest request = new RestRequest(Method.GET);
request.AddParameter("action", "getstatus");
var res = client.Execute(request);
However, this always fails with
System.IO.InvalidDataException: Block length does not match with its complement.
So the response does not contain any data.
What I noticed when I execute the request in a webrowser with a network tracer, it shows the Transfer-encoding as "chunked". This somehow seems to hinder RestSharp.
Running the same request with standard HttpWebRequest works fine.
Any ideas how to solve this with RestSharp?
//edit: The response should be a valid XML.

Categories

Resources