Using .NET Http client i login to jasper server.
HttpResponseMessage loginResponse = loginClient.PostAsync("http://localhost:8080/jasperserver/rest/login", formContent).Result;
IEnumerable<string> jaspsessid = loginResponse.Headers.GetValues("Set-Cookie");
Using above session id i pass to next request.
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Add("Cookie", jaspsessid);
httpClient.DefaultRequestHeaders.Accept.Add(new
System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
StringContent requestContent = constructJasperRequestJson(reportParameters);
HttpResponseMessage generateReportRequestResponse = new HttpResponseMessage();
generateReportRequestResponse = httpClient.PostAsync(AppConstant.JASPER_SERVER_BASE_URI + AppConstant.JASPER_SERVER_REPORT_EXECUTION_URI, requestContent).Result;
In second request i am getting 401.Unauthorized.
If anyone knows the issue,help me.
You could use a CookieContainer to hold the session cookie, rather than setting a header.
See How do I set a cookie on HttpClient's HttpRequestMessage for an example.
Related
I'm trying to use the Reddit API (https://github.com/reddit-archive/reddit/wiki/OAuth2) in my ASP.NET Core MVC app, and to obtain a token I have to make a POST to a URI with HTTP Basic Authorization (username and password being a client id and secret). Currently I use this code:
public async Task<HttpResponseMessage> HttpPost(string uri, string value)
{
HttpClient httpClient = new HttpClient();
HttpResponseMessage httpResponseMessage = await httpClient.PostAsync(uri, new StringContent(value));
return httpResponseMessage;
}
However, this doesn't use the authorization. How can I add authorization? I tried looking at the documentation for HttpClient.PostAsync and HttpContent, but I don't see anything relevant.
You will need to create a base64 encoded string with format: username:password. Then add it to Authorization header for Http Request.
Example:
using (var client = new HttpClient { BaseAddress = new Uri("https://baseUrl") })
{
var authString = Convert.ToBase64String(Encoding.UTF8.GetBytes("username:password"));
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authString);
var response = await client.PostAsync(requestUri, new StringContent(value));
}
I am working with an API service that requires Content-Type to be set to application/json;charset=UTF-8.
If I make a request without the charset=UTF-8 I get a 406 - Not Acceptable.
I can make a call through Postman setting the Content-Type as required, but if I use my .Net Http Client I get the error:
System.FormatException: 'The format of value
'application/json;charset=UTF-8' is invalid.'
Is there anyway I can work around this validation and force the Http Client to accept the value?
UPDATE:
Here is my latest attempt,it still throws the error.
Body.Headers.ContentType = new MediaTypeHeaderValue("application/json;charset=UTF-8");
UPDATE: Content-Type is indeed an invalid header. The API Developers removed it at our request.
Try to set the property:
new MediaTypeHeaderValue("application/json")
{
CharSet = Encoding.UTF8.WebName
};
Try this one
HttpClient httpClient= new HttpClient();
httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json; charset=utf-8");
Not sure if still relevant, but I recently ran into this same issue and was able to solve by setting the header in the following way:
string str = $"application/vnd.fmsstandard.com.Vehicles.v2.1+json; charset=UTF-8";
client.DefaultRequestHeaders.Add("Accept", str);
Try adding double quotes around UTF-8, like this:
Body.Headers.ContentType = new MediaTypeHeaderValue("application/json;charset=\"UTF-8\"");
EDIT:
Ok, try something like this. It's working for me locally with a WebApi I already had handy. Notice there is a header specification for what content-type will be ACCEPTED, and then there is a header for what content-type will be SENT with the request. For this example, both of them are JSON:
public static async Task<string> HttpClient(string url)
{
using(HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders
.Accept
.Add(new MediaTypeWithQualityHeaderValue("application/json")); // ACCEPT header
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "");
request.Content = new StringContent("{\"id\" : 1}",
Encoding.UTF8,
"application/json"); // REQUEST header
HttpResponseMessage response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
}
I only added the authentication header to it and it worked for me. AuthToken is either a string variable or the token itself. I left out the content type header and it just works. Below is the code; Response is a string that has to be serialized to a Jobject.
{
String Response = null;
HttpClient client = new HttpClient(CertByPass());
client.Timeout = TimeSpan.FromMinutes(5);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(AuthToken);
Response = await client.GetStringAsync(url);
}
Try creating a client helper class like:
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(whatever your url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
return client;
Issue: I am trying to use httpclient for fetching data from a site.Now the site requires you to first visit a link then only you can post data to the next link.
Link1 is a simple get request
Link2 is a post request
Now I think the site first store some cookie from the link1 and then only allow you to post data to link2 as whenever I try to open the link2 in incognito the site displays the error message "Session Timed out OR Maximum connections limit reached. Cannot Proceed Further. Please close and restart your browser "
Now I have tried this:
try
{
//Send the GET request
httpResponse = await httpClient.GetAsync(new Uri(link1UriString));
//Send the POSTrequest
httpResponse = await httpClient.PostAsync(new Uri(link2uriString),postContent);
httpResponseBody = await httpResponse.Content.ReadAsStringAsync();
}
But I am getting the session timed out error message. How to maintain cookies for a session in httpClient continuously received from the web.Like in python it can be done by
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookielib.CookieJar()))
urllib2.install_opener(opener)
Link1
Link2
You can use a CookieContainer to handle cookies for you.
Doing so, you'd create the HttpClient like this.
using System.Net;
using System.Net.Http;
CookieContainer cookies = new CookieContainer();
HttpClientHandler handler = new HttpClientHandler();
handler.CookieContainer = cookies;
HttpClient httpClient = new HttpClient(handler);
httpResponse = await httpClient.GetAsync(new Uri(link1UriString));
(Note it uses the version of HttpClient in System.Net.Http)
So, after first response you have Set-Cookie header:
var responseMessage = await httpClient.GetAsync("http://115.248.50.60/registration/Main.jsp?wispId=1&nasId=00:15:17:c8:09:b1");
IEnumerable<string> values;
var coockieHeader = string.Empty;
if (responseMessage.Headers.TryGetValues("set-cookie", out values))
{
coockieHeader = string.Join(string.Empty, values);
}
After that, just setup your cookie into request message:
var httpRequestMessage = new HttpRequestMessage
{
RequestUri = new Uri("http://115.248.50.60/registration/chooseAuth.do"),
Content = postContent,
Method = HttpMethod.Post
};
httpRequestMessage.Headers.Add("Cookie", values);
var httpResponse = await httpClient.SendAsync(httpRequestMessage);
I'm integrating a service that returns a key when I a GET request to a URL that is in the following format:
https://username:password#service.com/refresh.key
When I access the URL in my browser, it returns the new key as expected, by when I do a GET request using HttpClient I get a 401.
HttpClient _client = new HttpClient();
var response = await _client.GetAsync(#"https://username:password#service.com/refresh.key"); // Returns a 401
I think it has something to do with the '#' in the URL, but I'm not sure how to fix it, I tried replacing it with '%40', but when I do that I get a UriFormatException.
Does anyone know how to do this?
You should modify Authorization header of HttpClient, can you try the code below;
HttpClient _client = new HttpClient();
byte[] usernamePasswordBytes = Encoding.ASCII.GetBytes("user:pass");
_client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(usernamePasswordBytes));
var response = await _client.GetAsync(#"https://service.com/refresh.key");
PS: Such username:pass#domain.com requests are BasicAuthentication request so in fact you try to make basic authentication request.
Hope this works for you
You don't need to provide credentials in url. Instead you can do:
using (var handler = new HttpClientHandler {Credentials = new NetworkCredential("username", "password")}) {
using (HttpClient _client = new HttpClient(handler)) {
var response = await _client.GetAsync(#"https://service.com/refresh.key");
}
}
I am working with the Basecamp API which is a REST (JSON) API using basic HTTP authentication over HTTPS.
This should be a GET request but when I run my code using GET I am receiving:
Cannot send a content-body with this verb-type
When I run it as a POST, I receive:
{"status":"400","error":"Bad Request"}
Does anyone know why this may be occurring?
using (var httpClient = new HttpClient()) {
string userName = "someone#someone.com";
string password = "somepassword";
var credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(string.Format("{0}:{1}", userName, password)));
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Post, "https://correctUrlHere);
requestMessage.Headers.Add("User-Agent", "TheProject (someone#someone.com)");
requestMessage.Content = new StringContent(string.Empty, Encoding.UTF8, "application/json");
var response = await httpClient.SendAsync(requestMessage);
var responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseContent);
}
In this code I obviously swapped out the username, password, project name, and URL but in the actual code they are all correct.
GET requests must pass their parameters as url query and not as request body.
http://example.com?p1=1&p2=helloworld
If you don't have any content, as your example suggests, omit setting it on the request.
The BadRequest result indicates some error with your payload (again: content seems to be empty).