I have to make an HTTP persistent connection to a chinese security camera so I can obtain certain thermographic information. The manufacturer told me that they implemented HTTP persistent connection (I have never made persistent connections before).
This is the code I have right now:
var uri = new Uri($"http://<cam's IPv4>/ISAPI/Thermal/channels/2/thermometry/realTimethermometry/rules?format=json");
var credentialCache = new CredentialCache();
credentialCache.Add(uri, "Digest", new NetworkCredential("test", "test"));
using (var handler = new HttpClientHandler()
{
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
Credentials = credentialCache
})
{
using (var httpClient = new HttpClient(handler))
{
httpClient.DefaultRequestHeaders.Add("Connection", "Keep-Alive");
var response = await httpClient.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
return await response.Content.ReadAsStringAsync();
}
else
{
return null;
}
}
}
The thing is I'm not getting any response at all. How can I transform this code to HTTP 1.1 or make a persistent connection with this?.
For what I have been reading, there should only be an initial request and then I would keep receiving responses. Or at least that is what tbe manufacturer is telling me:
if you already called GET
/ISAPI/Thermal/channels/2/thermometry/realTimethermometry/rules?format=json
and established a connection, just receive alarms from the connection,
please do not call GET
/ISAPI/Thermal/channels/2/thermometry/realTimethermometry/rules?format=json
again
I have my web api which uses such code to get data from other api and do some operations with it :
var credential = new NetworkCredential("login", "password");
var myCache = new CredentialCache();
myCache.Add(uri, "Negotiate", credential);
var handler = new HttpClientHandler();
handler.AllowAutoRedirect = true;
handler.Credentials = myCache;
var httpClient = new HttpClient(handler);
var response = await httpClient.GetStringAsync(GetEmployeesUrl);
employees = JsonConvert.DeserializeObject<IEnumerable<EmployeeDto>>(response);
When I was debugging this code with IIS Express on my local host it's pretty good works and give me OK response from server. When I tried to deploy my api to real IIS this var response = await httpClient.GetStringAsync(GetEmployeesUrl);always returns 401 Unauthorized error.
Have someone some ideas what it can be? I have used webclient and webrequest they worked on my local machine but answer after deploy on server was the same.
From my web service (A) usng impersonation i would like call a WebAPI service (B) using HttpClient. But the service B always gets the system user of service A even though i do impersonation there.
var baseUri = "http://service/api/"
var handler = new HttpClientHandler { UseDefaultCredentials = true };
var client = new HttpClient(handler) { BaseAddress = baseUri };
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("ContentType", new List<string> { "application/json"});
var dataDto = new DataDto();
var json = JsonConvert.SerializeObject(dataDto );
var content = new StringContent(json);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var response = await client.PostAsync(SubUrl, content);
I know that Kerberos and SPN are set up correctly because it works using WebClient.
I think the problem is, that HttpClient.PostAsync creates a new task and therefore a new thread running under the credentials of the appPool of service A.
Does anyone know how i could force the task to run under the imperonated credentials?
I do not have access to the aspnet_config.config so the solution proveded here does not work for me.
Thanks a lot!
Tschuege
using (var client = new System.Net.Http.HttpClient())
{
var response = client.GetAsync(fullUrl).Result;
}
I am creating HTTP client as above to consume a RESTfull service.
I should be able to set proxy for this service request.
How can I set proxy server specific to this service request only?
System.Net.Http.HttpClient don't have TransportSettings propert and about Microsoft.Http assembly is unknown.
uSING Microsoft.Http I can
HttpClient client = new HttpClient();
/*Set Credentials to authenticate proxy*/
client.TransportSettings.Proxy = new WebProxy(proxyAddress);
client.TransportSettings.Proxy.Credentials = CredentialCache.DefaultCredentials;
client.TransportSettings.Credentials = CredentialCache.DefaultCredentials;
client.BaseAddress = new Uri(this.baseUrl);
var response = client.Get(fullUrl);
var jsonResponce = response.Content.ReadAsJsonDataContract<mYResponseoBJECT>();
public static T ReadAsJsonDataContract<T>(this HttpContent content)
{
return (T)content.ReadAsJsonDataContract<T>(new DataContractJsonSerializer(typeof(T)));
}
I'm trying to use an HttpClient for a third-party service that requires basic HTTP authentication. I am using the AuthenticationHeaderValue. Here is what I've come up with so far:
HttpRequestMessage<RequestType> request =
new HttpRequestMessage<RequestType>(
new RequestType("third-party-vendor-action"),
MediaTypeHeaderValue.Parse("application/xml"));
request.Headers.Authorization = new AuthenticationHeaderValue(
"Basic", Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "username", "password"))));
var task = client.PostAsync(Uri, request.Content);
ResponseType response = task.ContinueWith(
t =>
{
return t.Result.Content.ReadAsAsync<ResponseType>();
}).Unwrap().Result;
It looks like the POST action works fine, but I don't get back the data I expect. Through some trial and error, and ultimately using Fiddler to sniff the raw traffic, I discovered the authorization header isn't being sent.
I've seen this, but I think I've got the authentication scheme specified as a part of the AuthenticationHeaderValue constructor.
Is there something I've missed?
Your code looks like it should work - I remember running into a similar problem setting the Authorization headers and solved by doing a Headers.Add() instead of setting it:
request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "username", "password"))));
UPDATE:
It looks like when you do a request.Content, not all headers are being reflected in the content object. You can see this by inspecting request.Headers vs request.Content.Headers. One thing you might want to try is to use SendAsync instead of PostAsync. For example:
HttpRequestMessage<RequestType> request =
new HttpRequestMessage<RequestType>(
new RequestType("third-party-vendor-action"),
MediaTypeHeaderValue.Parse("application/xml"));
request.Headers.Authorization =
new AuthenticationHeaderValue(
"Basic",
Convert.ToBase64String(
System.Text.ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "username", "password"))));
request.Method = HttpMethod.Post;
request.RequestUri = Uri;
var task = client.SendAsync(request);
ResponseType response = task.ContinueWith(
t =>
{ return t.Result.Content.ReadAsAsync<ResponseType>(); })
.Unwrap().Result;
This would also work and you wouldn't have to deal with the base64 string conversions:
var handler = new HttpClientHandler();
handler.Credentials = new System.Net.NetworkCredential("username", "password");
var client = new HttpClient(handler);
...
Try setting the header on the client:
DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("{0}:{1}", userName, password))));
This works for me.
Also, consider that Redirect-Handler will clear the Authorization header if your request gets redirected.
So if you call an HTTP endpoint and it redirected to the HTTPS one, you will lose your authorization header.
request.Headers.Authorization = null;
Framework: .NET v6.0
Actually your problem is with PostAsync- you should use SendAsync. In your code - client.PostAsync(Uri, request.Content); sends only the content the request message headers are not included.
The proper way is:
HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = content
};
message.Headers.Authorization = new AuthenticationHeaderValue("Basic", credentials);
httpClient.SendAsync(message);