C# HttpClient和Windows身份验证: 无法访问已关闭的流

6

我正在使用本地的C# HTTP客户端并使用处理程序处理Windows身份验证,但是我遇到了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
            {

            }
        }
    }
}

有什么想法吗?
3个回答

1
经过一些新的调查,我认为/担心在HttpClientHandler(或HttpClient)中存在一个Microsoft bug
如果我使用SendAsync方法而不是PostAsync方法,我可以使用更多选项组合我的请求,尤其是将HTTP版本从默认的1.1更改为1.0。然后,在这种情况下,真正的异常被揭示出来了(不再被ObjectDisposedException异常隐藏/覆盖)。供您参考,我的真正异常如下: --> System.Net.WebException: 远程服务器返回错误:(401)未经授权。 --> System.ComponentModel.Win32Exception: 目标主体名称无效 (仍然提供信息,此异常是由于Active Directory中用户SPN的错误配置引起的)
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)
            {

            }
        }
    }
}

注意:降低HTTP版本只是一种获取真实异常信息的hack方法,HTTP 1.0已经非常老旧。任何专家分析都将不胜感激,希望这能帮助其他人。

0

你尝试过将PreAuthenticate设置为true吗?这会使用AD/User令牌添加授权标头,你应该会收到401错误,然后是第二个请求,其中包含标头。建议你在Fiddler中查看它。

httpClientHandler.PreAuthenticate = true;

首先感谢您的回复,不幸的是这并没有解决我的问题... - Kino101

0

您在评估之前就处理了HttpResponseMessage。请尝试使用以下代码。

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);
    }
}

哎呀,不行,我正在处理完响应后就将其释放了。 - Kino101

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接