I would like to know what is the proper way to send a get request to a URL with # in it, for example http://xxx/#/home in old angularjs that still has # in their route?
I am using the .net HttpClient class, and I tried
HttpResponseMessage response = await client.GetAsync("http://xxx/#/home");
and i am getting badrequest in response until i remove the # part.
Any ideas?
Thanks.
Related
I wanna send request to external API through the HttpClient from my own API in c#.
I am using dot net 5 and basic authentication.
Here is my code:
var client = new HttpClient
{
BaseAddress = new Uri(baseUrl)
};
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Put, "apiUrl");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var param = JsonConvert.SerializeObject(new
{
param1="",
param2=""
});
requestMessage.Content = new StringContent(param, Encoding.UTF8, "application/json");
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(Encoding.ASCII.GetBytes($"{user}:{pass}")));
HttpResponseMessage response = await client.SendAsync(requestMessage);
Usually, I send http request like this.
but now I have some problem.
After line HttpResponseMessage response = await client.SendAsync(requestMessage); authorization header removed from my request header and I got UnAuthorized http error.
I know that when redirection occurs, authorization header removed for security reason. Also I'm not sure about redirect in external API.
I add the HttpClientHandler with AllowAutoRedirect = false to my HttpClient
var handler = new HttpClientHandler()
{
AllowAutoRedirect = false,
};
var client = new HttpClient (handler)
{
BaseAddress = new Uri(baseUrl)
};
Now I got Redirect error 301(Permanently moved).
I decided to test the code in Postman. By default, when I call API in Postman, I got http error 405 method not allowed and error detail like this:
{
"detail": "Method "GET" not allowed."}
External API method is PUT. but here I got GET Error.
I tried many options in postman and finally I find the option in Postman:
When I toggle it on, external API work's properly.
Also I test it with Insomnia and it's work properly.
Does it related to my code or dot net 5 or what other thing in my code or it's related to external API?
If it's related to my code, How can I solve the error?
If error related to external API, why Postman and Insomnia response is ok?
External API has Core Policy for specific domain and I send request from other domain.
All I Know is that the CORS policy applied in browser. not in Postman, Insomnia or C# Code.
What about CORS? Does it related to CORS? if Yes, what shall I do?
I will be grateful for your answer.
Update
I detect WWW-Authenticate: JWT realm="api" in the response header.
What exactly is it? and what shall I do?
I find out the problem. It's really Ridiculous.
When I use URL like www.abc.com/api/something the request gets 301 error and postman sends another request like www.abc.com/api/something/. The difference is just / at the end of request.
I tried new URL in postman and first request got ok.
Also I tried URL in my C# code and again its ok.
But i could not understand why.
Thanks a lot dear #pharaz-fadaei
You are right about the removal of authorization headers after redirects. But keep in mind that this behavior is part of the design of the HttpClient in C#. Postman and Insomnia may have different mechanisms to send the authorization headers on each consecutive request that is caused by redirects. The option that you enabled in Postman will make it use the original HTTP method you specified (PUT) as the HTTP method to send further requests based on the redirect messages (Postman uses GET method by default on requests instructed by redirect messages).
The fact that you see a 301 shows that a redirection is required. You can check Location header value in response.Headers to see the real location and send your requests with the authorization headers to that endpoint directly. If I were you I wouldn't use the new location directly because the original endpoint is what you were given by the authors of the API. Instead I would programmatically send the request to the original endpoint and resend the request on 301 codes to the new Location (use PUT method due to the behavior of Postman) until you get the result. This answer can give you some ideas: https://stackoverflow.com/a/42566541/1539231
Since you see WWW-Authenticate: JWT realm="api" header, the external API is required a JWT token authentication, not basic authentication. I think first you might need to check external api's documentation.
I have defined a route in WordPress using register_rest_route, this is set as a route that accepts only POST requests:
register_rest_route( 'myNamespace', '/myRoute/', array(
'methods' => 'POST',
'callback' => 'myCallbackFunction',
) );
Making a POST request to this route using Postman returns the result I expect. However, making a request from a C# application using either System.Net.Http.HttpClient or System.Net.HttpWebRequest I receive a 404 response.
When I change my register_rest_route to accept GET requests, using the code below, my request is received, but fails because I need values posted in the body of the request.
register_rest_route( 'myNamespace', '/myRoute/', array(
'methods' => 'GET',
'callback' => 'myCallbackFunction',
) );
This is extremely peculiar and I cannot figure out why making the request from a C# application converts a HttpPost to a HttpGet request, but works perfectly fine when making the request from Postman.
I'm using .NET 4.8 SDK for my C# application and WordPress 5.3.2 for WordPress.
Right now I cannot figure out where the issue lies. At first I thought it was an issue with my C# application, so I changed the request tools from HttpWebRequest to HttpClient, but that did not fix the issue. Then I thought it was an issue with the PHP side of things, but Postman works fine.
I don't understand how the request method is changing in transit?
I am trying to use a Rest API from outside my company's domain. My problem is when I run the POST request within Postman or an Angular application it works fine. But when I send the same payload within a winforms c# application, I get Access Forbidden. You have browsed from an unrecognized IP address. The proxy therefore denied access to this site.
I thought the problem was with the payload itself, so I copied the same JSON string, sent it via postman and It worked. So I thought perhaps the issue is with the server itself, so I ran other GET requests to the same server and they worked. I tried sending an empty string to the POST request and it worked, tried an empty object and get FORBIDDEN REQUEST. The same code, I ran it from my personal computer and it worked.
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", sToken);
StringContent sRequestContent = new StringContent(requestPayload, Encoding.UTF8, "application/json");sRequestContent).Result;
var result = client.PostAsync(new Uri(sUrl), sRequestContent).Result;
return result.Content.ReadAsStringAsync().Result;
PS:
requestPayload is a JSON string.
I tried below code as I wanted to send a http PUT request to a REST Api. The sample request looks like
http://localhost/SomeWebServices/some/something/setsomething?ID=12121212&Number=121212&Product=BUISCUITE&EffectiveDate=2015-10-22
WebClient request = new WebClient();
request.QueryString.Add("CustomerNumber", "bla");
request.QueryString.Add("AccountNumber", "bla");
request.UploadString(new Uri(BaseUrl + ServiceEndPoint), "PUT", String.Empty);
When I debug the code I am getting a 401 Unauthorized error, Am I doing the correct thing to make a HTTP PUT request ? Is there a way to intercept the request to see if its in correct format. My service is hosted in local IIS instance. Although I have used WebClient() you are more than welcome to share your elegant approach if there is a better & easy way. Thanks.
http://www.jfrog.com/confluence/display/RTF/Artifactory+REST+API#ArtifactoryRESTAPI-CreateorReplaceRepositoryConfiguration
I am using the Create or Replace Repository Configuration call. However I am getting a 406 Error: Not Acceptable. Other PUT calls are working but do not return JSON. I believe JSON is the source of the error but have not been able to resolve or prove this.
I have added the code as below
RestClient Client = new RestClient(uriString);
RestRequest Request = new RestRequest(requestType);
Request.AddHeader("Authorization", "Basic " + credentials);
Request.AddHeader("Accept", "application/json");
I've seen threads where adding the header to accept JSON resolves the error but this has not worked for me.
A 406 HTTP status means that if a web server detects that the data it wants to return is not acceptable to the client, it returns a header containing the 406 error code.
The client can define the characteristics of the data it will accept back from the web server by using the accept headers.
In this case you declare the you would like to accept application/json:
Request.AddHeader("Accept", "application/json");
however the REST API method you are invoking is returning text/plain.
You should change the code to accept text/plain:
Request.AddHeader("Accept", "text/plain");
Wanted to add this for for future users stuck like me. I was having the same issue and tried the request with Postman and saw that the Content-Type was "application/hal+json" I was trying it with application/json without luck.
So running a test in postman I was able to figure out what the server needed exactly.
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/hal+json"));
I faced the same 406 Error: Not Acceptable when trying to get JSON on another site. In my case I could see correct JSON when typed url in my browser address field. But downloading it from the same url via my C# code have been producing 406 Error.
None of the answers in this topic solved my problem directly. But at least they pointed out to me that's the point is HTTP headers.
So I googled that page:
https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending
and added all browser headers to my code, and voila! It started to work.
In my case it was enough to fill some data in user-agent header.
First, the Accept header states what the client is ready to get back, not what the client sends.
The header that states what the client sends is Content-Type.
Also, this method does not accept application/json. As clearly stated in the docs, it accepts one of the following:
application/vnd.org.jfrog.artifactory.repositories.LocalRepositoryConfiguration+json
application/vnd.org.jfrog.artifactory.repositories.RemoteRepositoryConfiguration+json
application/vnd.org.jfrog.artifactory.repositories.VirtualRepositoryConfiguration+json