Reputation: 993
I'm using the native C# HTTP client with a handler to process Windows Authentication and I'm having ObjectDisposedException
.
using (var httpClientHandler = new HttpClientHandler { Credentials = CredentialCache.DefaultNetworkCredentials })
{
bool disposeHandler = true; //Setting true or false does not fix the problem
using (var httpClient = new HttpClient(httpClientHandler, disposeHandler))
{
using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes("Hello")))
{
// Commenting/uncommenting the line below does not fix the problem
// httpRequestMessage.Headers.Connection.Add("Keep-Alive");
using (var httpResponseMessage = await httpClient.PostAsync("http://SomeUrl", content)) // This line throws an ObjectDisposedException
{
}
}
}
}
Any idea?
Upvotes: 6
Views: 3170
Reputation: 4845
You're disposing of your HttpResponseMessage
before it's had a chance to be evaluated. Try this instead.
HttpResponseMessage httpResponseMessage = null;
using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes("Hello")))
{
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "http://SomeUrl")
{
Content = content,
Version = HttpVersion.Version10
};
using (var httpClient = new HttpClient(httpClientHandler, disposeHandler))
{
httpResponseMessage = await httpClient.SendAsync(httpRequestMessage);
}
}
Upvotes: 0
Reputation: 993
After some new investigations, I think/fear there it is a Microsoft bug in HttpClientHandler (or HttpClient):
If instead of using the PostAsync method I use the SendAsync method, I can compose my request with more options and especially change the HTTP version from 1.1 (by default) to 1.0. Then in this case the real exception was revealed (and it was not anymore hidden/overridden by the ObjectDisposedException exception). For your information, my real exception was the following:
--> System.Net.WebException: The remote server returned an error: (401) Unauthorized.
--> System.ComponentModel.Win32Exception: The target principal name is incorrect
(Still for your information, this exception was due to a bad configuration of an SPN of a user in the Active Directory)
using (var httpClientHandler = new HttpClientHandler { Credentials = CredentialCache.DefaultNetworkCredentials })
{
bool disposeHandler = true; //Setting true or false does not fix the problem
using (var httpClient = new HttpClient(httpClientHandler, disposeHandler))
{
using (var content = new ByteArrayContent(Encoding.UTF8.GetBytes("Hello")))
{
// Commenting/uncommenting the line below does not fix the problem
// httpRequestMessage.Headers.Connection.Add("Keep-Alive");
var httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, "http://SomeUrl")
{
Content = content,
Version = HttpVersion.Version10
};
using (var httpResponseMessage = await httpClient.SendAsync(httpRequestMessage)) // This line still throws but with the real exception (and not the ObjectDisposedException)
{
}
}
}
}
Beware: downgrading the HTTP version is just a hack to get the real exception message, HTTP 1.0 is getting very old.
Any experts analysis would be really appreciated. Hope this will help others.
Upvotes: 1
Reputation: 2405
Have you tried setting PreAuthenticate = true, it will add the authorization header with the AD/User token, you should get a 401 followed by a second request, with the header, suggest you view it in fiddler.
httpClientHandler.PreAuthenticate = true;
Upvotes: 0