问题
I am using FlurlHttp and I want to disable AllowAutoRedirect for some API calls. I know How can I get System.Net.Http.HttpClient to not follow 302 redirects?
WebRequestHandler webRequestHandler = new WebRequestHandler();
webRequestHandler.AllowAutoRedirect = false;
HttpClient httpClient = new HttpClient(webRequestHandler);
// Send a request using GetAsync or PostAsync
Task<HttpResponseMessage> response = httpClient.GetAsync("http://www.google.com")
But for Flurl I found only the way similar to described in C# Flurl - Add WebRequestHandler to FlurlClient (I haven't compiled yet the code below , so it may have some errors)
public class HttpClientFactoryWithWebRequestHandler : DefaultHttpClientFactory
{
private readonly WebRequestHandler _webRequestHandler;
public HttpClientFactoryWithWebRequestHandler (WebRequestHandler webRequestHandler )
{
_webRequestHandler = webRequestHandler ;
}
public override HttpMessageHandler CreateMessageHandler()
{
var handler =_webRequestHandler ;
//Or var handler = new WebRequestHandler(_webRequestHandler );
return handler;
}
}
Then I can pass the setting for a new FlurlClient:
WebRequestHandler webRequestHandler = new WebRequestHandler();
webRequestHandler.AllowAutoRedirect = false;
var fc = new FlurlClient(url)
.ConfigureClient(c => c.HttpClientFactory =
new HttpClientFactoryWithWebRequestHandler (webRequestHandler));
It looks more complicated that it could be. Is it the right way to do or it can be done simplier?
回答1:
It feels a little heavy because it's a scenario that Flurl doesn't support directly, so it requires tinkering under the hood a bit. You're on the right track but I think there's a few ways you could simplify it. First, I'd suggest creating the WebRequestHandler
inside the factory. Creating it externally and passing it in seems unnecessary.
public class NoRedirectHttpClientFactory : DefaultHttpClientFactory
{
public override HttpMessageHandler CreateMessageHandler()
{
return new WebRequestHandler { AllowAutoRedirect = false };
}
}
If you want this behavior app-wide by default, you could register it globally on startup. Then you don't need to do anything with individual FlurlClient
s.
FlurlHttp.Configure(settings =>
settings.HttpClientFactory = new NoRedirectHttpClientFactory());
Otherwise, if you need the ability to pick and choose which FlurlClient
s you disable it for, an extension method would make it a little easier:
public static IFlurlClient WithoutRedirects(this IFlurlClient fc) {
fc.Settings.HttpClientFactory = new NoRedirectHttpClientFactory();
return fc;
}
Then use it like this:
new FlurlClient(url).WithoutRedirects()...
回答2:
My implementation is based on Todd's answer (minor class/method name changes)
Example of use:
var resp = await new FlurlClient(url).DisableRedirects().Request().AllowAnyHttpStatus().GetAsync();
resp.StatusCode.Should().Be(HttpStatusCode.Found);//302
Implementation:
public class HttpClientFactoryWithWebRequestHandler : DefaultHttpClientFactory
{
private readonly HttpMessageHandler _httpMessageHandler;
public HttpClientFactoryWithWebRequestHandler(HttpMessageHandler httpMessageHandler)
{
_httpMessageHandler = httpMessageHandler;
}
public override HttpMessageHandler CreateMessageHandler()
{
var handler = _httpMessageHandler;
return handler;
}
}
public static class FlurlClientExtensions
{
public static IFlurlClient DisableRedirects(this IFlurlClient fc)
{
var httpClientHandler = new HttpClientHandler {AllowAutoRedirect = false};
fc.Settings.HttpClientFactory = new HttpClientFactoryWithWebRequestHandler(httpClientHandler);
return fc;
}
}
来源:https://stackoverflow.com/questions/46615548/disable-autoredirect-in-flurlclient