gpt4 book ai didi

c# - 在 Windows 窗体的 HttpClient 类中使用 DelegatingHandler - 尚未设置内部处理程序

转载 作者:可可西里 更新时间:2023-11-01 03:14:17 25 4
gpt4 key购买 nike

首先,我收到的错误消息如下: 尚未设置内部处理程序

我正在编写一个自定义消息处理程序来处理我的 API 的身份验证 cookie 超时。例如,如果我的代码库调用 API 并收到 401,那么它应该重试登录 url 以获取更新的 cookie。我计划按如下方式完成此操作:

public class CkApiMessageHandler : DelegatingHandler
{
private readonly string _email;
private readonly string _password;
private const string _loginPath = "Account/Login";

public CkApiMessageHandler(string email, string password)
{
_email = email;
_password = password;

//InnerHandler = new HttpControllerDispatcher(null);
}

protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{

var response = await base.SendAsync(request, cancellationToken);

if(response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
{
Logging.Logger.LogInformation("Authentication cookie timed out");
var baseAddress = request.RequestUri.Host;
var loginPath = baseAddress + _loginPath;

var originalRequest = request;

var loginRequest = new HttpRequestMessage(new HttpMethod("POST"), loginPath);
var dict = new Dictionary<string, string>();
dict.Add("Email", _email);
dict.Add("Password", _password);

var form = new FormUrlEncodedContent(dict);
loginRequest.Content = form;
loginRequest.Headers.Clear();

foreach(var header in originalRequest.Headers)
{
loginRequest.Headers.Add(header.Key, header.Value);
}

var loginResponse = await base.SendAsync(loginRequest, cancellationToken);

if (loginResponse.IsSuccessStatusCode)
{
Logging.Logger.LogInformation("Successfully logged back in");
return await base.SendAsync(originalRequest, cancellationToken);
}
else
{
Logging.Logger.LogException(new Exception("Failed to log back in"), "Could not log back in");
}
}

return response;
}


}

我正在将一个用于直接访问数据库的旧服务转换为一个访问 web api 的服务,我试图在不必更改此类的任何使用者的情况下完成此操作。因此出现了奇怪的处理程序.这是服务类中的示例方法。

 public void UpdateClientInstallDatabaseAndServiceData(string dbAcronym, string clientVersion, string clientEnginePort, Guid installationId, string sqlserver)
{
var dict = new Dictionary<string, string>();
dict.Add("dbAcronym", dbAcronym);
dict.Add("clientVersion", clientVersion);
dict.Add("clientEnginePort", clientEnginePort);
dict.Add("desktopClientId", installationId.ToString());
dict.Add("sqlServerIp", sqlserver);

var form = new FormUrlEncodedContent(dict);

_client.PostAsync(_apiPath + "/UpdateClientInstallDatabaseAndServiceData", form);
}

因此,如果上述代码因 401 而失败,服务将自动重新登录并重试原始代码,而服务的消费者无需检查请求并重新登录。消费者不应该知道它正在处理一个网络 API。

我的问题是我的消息处理程序期望设置一个 InnerHandler,这需要一个 HttpConfiguration 类的实例。当我查看规范时 here ,它似乎是某种用于设置 Web API 服务的类。这很好,只是这段代码不是在 api 中执行的。它是在 Windows 窗体应用程序上执行的。委托(delegate)处理程序在 HttpClient 类中使用,如下所示......

_client = new HttpClient(new CKEnterprise.Common.CkApiMessageHandler(email, password));  

所以我的问题是:我怎样才能让这个 DelegatingHandler 在 Web API 项目的上下文之外完成它的工作?

进行更新。看起来我可以只使用 HttpClientHandler 类 https://blogs.msdn.microsoft.com/henrikn/2012/08/07/httpclient-httpclienthandler-and-webrequesthandler-explained/

最佳答案

我应该早点意识到这一点,但将内部处理程序设置为 HttpClient 使用的 default 处理程序是有意义的。因此,在 DelegatingHandler 的子类中,您应该将内部处理程序设置为 HttpClient 使用的默认处理程序,如下所示:

    public CkApiMessageHandler(string email, string password, Guid moduleId)
{
_email = email;
_password = password;
_moduleId = moduleId;
InnerHandler = new HttpClientHandler();

}

关于c# - 在 Windows 窗体的 HttpClient 类中使用 DelegatingHandler - 尚未设置内部处理程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43701267/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com