Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在FlurlClient上链接的多个工厂方法_C#_Flurl - Fatal编程技术网

C# 在FlurlClient上链接的多个工厂方法

C# 在FlurlClient上链接的多个工厂方法,c#,flurl,C#,Flurl,我正试图通过FlurlClient向一些网站提出一些请求。 但是我需要把我在工厂写的一些方法链接起来 我使用这种方法创建代理和允许自动重定向工厂 允许自动重定向扩展名: public static IFlurlClient AllowAutoRedirect(this IFlurlClient fc, bool allowAutoRedirect) { fc.Settings.HttpClientFactory = new CustomFlurlHttpClientFactory(all

我正试图通过
FlurlClient
向一些网站提出一些请求。 但是我需要把我在工厂写的一些方法链接起来

我使用这种方法创建
代理
允许自动重定向
工厂

允许自动重定向扩展名:

public static IFlurlClient AllowAutoRedirect(this IFlurlClient fc, bool allowAutoRedirect)
{
    fc.Settings.HttpClientFactory = new CustomFlurlHttpClientFactory(allowAutoRedirect);
     return fc;
}
public static IFlurlClient Proxy(this IFlurlClient fc, DML.Proxy proxy)
{
      fc.Settings.HttpClientFactory = new CustomFlurlHttpClientFactory(proxy);
      return fc;
}
代理扩展:

public static IFlurlClient AllowAutoRedirect(this IFlurlClient fc, bool allowAutoRedirect)
{
    fc.Settings.HttpClientFactory = new CustomFlurlHttpClientFactory(allowAutoRedirect);
     return fc;
}
public static IFlurlClient Proxy(this IFlurlClient fc, DML.Proxy proxy)
{
      fc.Settings.HttpClientFactory = new CustomFlurlHttpClientFactory(proxy);
      return fc;
}
最后,这是我的工厂方法

private Proxy _proxy;
private bool? _allowAutoRedirect;

public CustomFlurlHttpClientFactory(Proxy proxy)
{
     _proxy = proxy;
}


public CustomFlurlHttpClientFactory (bool? allowAutoRedirect)
{
    _allowAutoRedirect = allowAutoRedirect;
}


public override HttpClient CreateHttpClient(HttpMessageHandler handler)
{
    return base.CreateHttpClient(handler);
}


public override HttpMessageHandler CreateMessageHandler()
{
    if(_proxy != null)
        return ProxyClientHandlerConfiguration();


    if (_allowAutoRedirect != null)
        return AutoRedirectClientHandlerConfiguration();


    return base.CreateMessageHandler();
}

private HttpClientHandler AutoRedirectClientHandlerConfiguration() => new HttpClientHandler { AllowAutoRedirect = _allowAutoRedirect ?? true };


private HttpClientHandler ProxyClientHandlerConfiguration() => 
    new HttpClientHandler {
        Proxy = new WebProxy {
            Address = _proxy.GetFullUri(),
            BypassProxyOnLocal = true,
            UseDefaultCredentials = _proxy.UseDefaultCredentials()
        },
        UseProxy = true
    };

但是,当创建客户机时,只有第二个方法正确执行(Proxy)

我知道,当我调用
AllowAutoRedirect
时,它会返回一个新的
HttpClientHandler
,当调用
Proxy
时,它会覆盖
AllowAutoRedirect
返回的
HttClientHandler

var cli = new FlurlClient(url)
             .WithHeaders(headers)
             .WithCookies(cookies)
             .AllowAutoRedirect(false) /*Custom Factory Method*/
             .Proxy(proxy) /*Custom Factory Method*/
             .EnableCookies(); 

因此,如何使用这两种方法只获得一个
HttpClientHandler
AllowAutoRedirect
Proxy

这里的问题是,您的扩展方法每次都会用一个新的工厂覆盖现有工厂,所以最后一个总是“赢”。您需要编辑自定义工厂(如果存在),而不是替换它。开始使工厂可编辑。大概是这样的:

public class CustomHttpClientFactory : DefaultHttpClientFactory
{
    public bool? AutoRedirect { get; set; }
    public Proxy Proxy { get; set; }

    public override HttpMessageHandler CreateMessageHandler()
    {
        var handler = new HttpClientHandler();

        if (AutoRedirect != null)
            handler.AllowAutoRedirect = AutoRedirect;

        if (Proxy != null) {
            handler.Proxy = new WebProxy { ... };
            handler.UseProxy = true;
        }

        return handler;
    }
}
public static IFlurlClient AllowAutoRedirect(this IFlurlClient fc, bool allowAutoRedirect)
{
    var fac = fc.Settings.HttpClientFactory as CustomHttpClientFactory ??
        new CustomHttpClientFactory();
    fac.AutoRedirect = allowAutoRedirect;
    fc.Settings.HttpClientFactory = fac;
    return fc;
}

public static IFlurlClient Proxy(this IFlurlClient fc, Proxy proxy)
{
    var fac = fc.Settings.HttpClientFactory as CustomHttpClientFactory ??
        new CustomHttpClientFactory();
    fac.Proxy = proxy;
    fc.Settings.HttpClientFactory = fac;
    return fc;
}
那么您的扩展方法应该如下所示:

public class CustomHttpClientFactory : DefaultHttpClientFactory
{
    public bool? AutoRedirect { get; set; }
    public Proxy Proxy { get; set; }

    public override HttpMessageHandler CreateMessageHandler()
    {
        var handler = new HttpClientHandler();

        if (AutoRedirect != null)
            handler.AllowAutoRedirect = AutoRedirect;

        if (Proxy != null) {
            handler.Proxy = new WebProxy { ... };
            handler.UseProxy = true;
        }

        return handler;
    }
}
public static IFlurlClient AllowAutoRedirect(this IFlurlClient fc, bool allowAutoRedirect)
{
    var fac = fc.Settings.HttpClientFactory as CustomHttpClientFactory ??
        new CustomHttpClientFactory();
    fac.AutoRedirect = allowAutoRedirect;
    fc.Settings.HttpClientFactory = fac;
    return fc;
}

public static IFlurlClient Proxy(this IFlurlClient fc, Proxy proxy)
{
    var fac = fc.Settings.HttpClientFactory as CustomHttpClientFactory ??
        new CustomHttpClientFactory();
    fac.Proxy = proxy;
    fc.Settings.HttpClientFactory = fac;
    return fc;
}

请注意,如果您从不同的线程为相同的
FlurlClient
命中这些扩展方法,那么最终可能会出现争用条件。但是,由于它们是关于配置客户机而不是请求的,希望您只需配置一次(每个客户机),这不是一个问题。

您可以发布您对
AllowAutoRedirect()
和/或
Proxy()
的定义吗?我编辑了这个问题@托德梅尼尔