标签: dotnet-httpclient

C# HttpClient - 我可以强制关闭连接吗?

我们发现一个问题,即客户访问我们的 API 并在请求完成之前取消请求。我们相信他们也会关闭连接,因此请求不会写入 IIS 日志。我正在尝试创建一个跑步者来复制这种行为。我不明白的是如何强制关闭连接以使服务器无法发回数据?

这是我当前的代码:

 private static async Task RunMe()
    {

        var cts = new CancellationTokenSource();
        cts.CancelAfter(5000);

        using (var client = new HttpClient())
        {
            try
            {
                client.DefaultRequestHeaders.ConnectionClose = true;
                client.DefaultRequestHeaders.Add("x-apikey", "some key");
                Console.WriteLine("making request");
                using (var response = await client.GetAsync("https://foo.com/api/apitest/testcancel", cts.Token))
                {
                    var result = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($"Request completed: {result}");
                }
            }
            finally
            {                    
                client.CancelPendingRequests();
                Console.WriteLine("about to dispose the client");
                client.Dispose();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

代码在 5 秒后正确取消请求,但 IIS 似乎仍在 API 调用完成后发回数据(设置为 10 秒)。

如何关闭连接以便 IIS 在 5 …

c# iis dotnet-httpclient

4
推荐指数
1
解决办法
2万
查看次数

如何使用HttpClient从特定IP地址发送请求?C#

我的服务器上有多个 IP,并且想在使用 HttpClient 类从 API 获取/发布数据时选择使用其中一个。(或者甚至同时发送请求,但使用 2 个 IP,而不仅仅是一个)

我已经看到一些使用 HttpWebRequest (此处)的示例,这些示例利用委托,但我想继续使用 HttpClient 实现。

c# dotnet-httpclient asp.net-web-api2

4
推荐指数
1
解决办法
6213
查看次数

C#:即使使用 httpclient 发送 CSRF 令牌后也会收到 403

我正在尝试从我的 UWP 应用程序将有效负载发布到我们的后端系统。为此,我首先执行 GET 来获取 CSRF 令牌,然后将其添加到 POST 请求的标头中。发帖时,我仍然收到 403 Forbidden 错误。

我正在与“Insomnia”REST 客户端进行交叉测试,方法是执行单独的 GET 和 POST 请求,并将从 GET 获取的 CSRF 令牌提供给 POST 标头,并且工作正常。

获取令牌:

public async Task<string> GetCSRF()
{
    using (HttpClient httpClient = new HttpClient())
    {
        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(
            System.Text.Encoding.ASCII.GetBytes(
                    string.Format("{0}:{1}", userName.Text.ToUpper(), SAPpassword.Password))));

        httpClient.DefaultRequestHeaders.Add("X-CSRF-TOKEN", "fetch");
        HttpResponseMessage response = await httpClient.GetAsync(new Uri(_URI));
        response.EnsureSuccessStatusCode();
        if (response.Content == null)
            return null;
        String csrfToken = response.Headers.GetValues("X-CSRF-TOKEN").FirstOrDefault();
        return csrfToken;
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到了带有 csrf 令牌的以下标头:

public async Task<string> GetCSRF()
{
    using (HttpClient httpClient …
Run Code Online (Sandbox Code Playgroud)

c# csrf dotnet-httpclient

4
推荐指数
1
解决办法
7211
查看次数

Polly 的 Policy.TimeoutAsync 不适用于异步上下文中的 PolicyWrap

这是一个完全有效的示例(复制/粘贴它并尝试一下,只需获取 Polly Nuget)

我有以下控制台应用程序代码,它向“ http://ptsv2.com/t/v98pb-1521637251/post ”上的 HTTP 客户端沙箱发出 POST 请求(您可以访问此链接“ http://ptsv2.com/ t/v98pb-1521637251 “查看配置或让自己成为一个“厕所”):

class Program
{
    private static readonly HttpClient _httpClient = new HttpClient()
        ; //WHY? BECAUSE - https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/
    static void Main(string[] args)
    {
        _httpClient.BaseAddress = new Uri(@"http://ptsv2.com/t/v98pb-1521637251/post");
        _httpClient.DefaultRequestHeaders.Accept.Clear();
        _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));

        var result = ExecuteAsync("Test").Result;
        Console.WriteLine(result);
        Console.ReadLine();
    }

    private static async Task<string> ExecuteAsync(string request)
    {
        var response = await Policies.PolicyWrap.ExecuteAsync(async () => await _httpClient.PostAsync("", new StringContent(request)).ConfigureAwait(false));
        if (!response.IsSuccessStatusCode)
            return "Unsuccessful";
        return await response.Content.ReadAsStringAsync().ConfigureAwait(false);
    }
}
Run Code Online (Sandbox Code Playgroud)

Http 客户端等待 4 秒,然后返回响应。

我已经设置了这样的策略( …

c# asynchronous timeout dotnet-httpclient polly

4
推荐指数
1
解决办法
5217
查看次数

HttpClient GetStringAsync 返回 301,但浏览器能够导航到正确的地址

我认为HttpClient应该能够处理301错误代码,并重定向到正确的地址。但是,使用以下地址(https://www.npr.org/templates/rss/podcast.php?id=510298),它会抛出异常。不过浏览器能够正确处理它。只是想了解是否有出路或者我错过了什么。

HttpClient client = new HttpClient();

var s = await client
    .GetStringAsync("https://www.npr.org/templates/rss/podcast.php?id=510298");
Run Code Online (Sandbox Code Playgroud)

投掷

Test1 [0:00.779] Failed: System.Net.Http.HttpRequestException : Response 
status code does not indicate success: 301 (Moved Permanently).
System.Net.Http.HttpRequestException : Response status code does not 
indicate success: 301 (Moved Permanently).
   at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode()
   at System.Net.Http.HttpClient.GetStringAsyncCore(Task`1 getTask)
   at XUnitTestProject1.UnitTest1.Test1() in 
   C:\Users\res\source\repos\test\XUnitTestProject1\UnitTest1.cs:line 13
Run Code Online (Sandbox Code Playgroud)

c# http-status-code-301 dotnet-httpclient

4
推荐指数
1
解决办法
1357
查看次数

在单个单元测试中多次模拟 httpclient

嗨,我正在尝试模拟 httpclient,显然是强迫它给我我需要的结果。问题是,在我的单元测试中,我必须模拟 httpClient 两次,每次都有不同的响应。

...
...
            var httpReq = new HttpRequestMessage(
            HttpMethod.Get,
            $"{config["MY_TEST_ENDPOINT"]/site1}");

            var myContent = await response.Content.ReadAsStringAsync();
            var myFirstModel = JsonConvert.DeserializeObject<MyFirstModel>(myContent );
...
...
Run Code Online (Sandbox Code Playgroud)

我嘲笑这可能:

...
myMockedHttp
            .Protected()
            .Setup<Task<HttpResponseMessage>>(
                "SendAsync",
                ItExpr.IsAny<HttpRequestMessage>(),
                ItExpr.IsAny<CancellationToken>())
            .ReturnsAsync(new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.OK,
                Content = new StringContent("[{'id':'0001'," +
                                            "'name':'Jonah'," +
                                            "'street':'Cambridge Street 1234'}]"
                                            )
            })
            .Verifiable();
Run Code Online (Sandbox Code Playgroud)

这会给我一个响应,我可以反序列化和使用它 - 给它一个包含 3 个成员的对象:id、name 和 street。

这对我来说是一个问题 - 我也在同一个单元测试中进行了另一个 httpclient 调用,但我不知道如何模拟它。事情是这样的:

...
...
            var httpReq = new HttpRequestMessage(
            HttpMethod.Get,
            $"{config["MY_TEST_ENDPOINT"]/site2}");

            var httpResponseMsg = …
Run Code Online (Sandbox Code Playgroud)

c# serialization unit-testing moq dotnet-httpclient

4
推荐指数
1
解决办法
2599
查看次数

使用 Polly 进行 HttpClient 单元测试

我正在寻找HttpClient对 a进行单元测试Polly RetryPolicy,并且我正在尝试找出如何控制响应的内容HTTP

我在客户端上使用了 a HttpMessageHandler,然后覆盖发送异步,这效果很好,但是当我添加 Polly 重试策略时,我必须使用 a 创建 HTTP 客户端的实例IServiceCollection,并且无法HttpMessageHandler为客户端创建 a。我尝试过使用,.AddHttpMessageHandler()但这会阻止轮询重试策略,并且只会触发一次。

这就是我在测试中设置 HTTP 客户端的方式

IServiceCollection services = new ServiceCollection();

const string TestClient = "TestClient";
 
services.AddHttpClient(name: TestClient)
         .AddHttpMessageHandler()
         .SetHandlerLifetime(TimeSpan.FromMinutes(5))
         .AddPolicyHandler(KYA_GroupService.ProductMessage.ProductMessageHandler.GetRetryPolicy());

HttpClient configuredClient =
                services
                    .BuildServiceProvider()
                    .GetRequiredService<IHttpClientFactory>()
                    .CreateClient(TestClient);

public static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
    return HttpPolicyExtensions
            .HandleTransientHttpError()
            .WaitAndRetryAsync(6,
                retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
                onRetryAsync: OnRetryAsync);
}

private async static Task OnRetryAsync(DelegateResult<HttpResponseMessage> outcome, TimeSpan timespan, int retryCount, Context context)
{ …
Run Code Online (Sandbox Code Playgroud)

c# unit-testing dotnet-httpclient polly retry-logic

4
推荐指数
1
解决办法
9107
查看次数

IHttpClientFactory 并更改基础 HttpClient.BaseAddress

IHttpClientFactory 和更改 HttpClient.BaseAddress 的最佳实践是什么?

在创建我的依赖注入时,我是这样做的:

services.AddHttpClient("MyApp", c =>
    {
        c.BaseAddress = new Uri("https://myurl/");
        c.DefaultRequestHeaders.Add("Accept", "application/json");
    }).ConfigurePrimaryHttpMessageHandler(handler => new HttpClientHandler()
    { AutomaticDecompression = DecompressionMethods.GZip });
Run Code Online (Sandbox Code Playgroud)

然后当我需要一个 HttpClient 这样做时:

var client = clientFactory.CreateClient("MyApp");
Run Code Online (Sandbox Code Playgroud)

这很有效,但有时在运行时需要更改 BaseAddress。在运行期间,我无法在注入后更改 BaseAddress。现在我可以完全忽略 BaseAddress 并在 API 调用中发送整个地址,但是,我不知道这是否是正确的做法。像这样的东西:

await using var stream = await client.GetStreamAsync($"{addresss}/{api}");
using var streamReader = new StreamReader(stream);
using var textReader = new JsonTextReader(streamReader);
var serializer = new JsonSerializer();
data = serializer.Deserialize<List<T>>(textReader);
Run Code Online (Sandbox Code Playgroud)

c# wpf dependency-injection dotnet-httpclient

4
推荐指数
1
解决办法
2204
查看次数

Windows 上的 .net core 3.0 忽略了 NO_PROXY

我们正在尝试让代理功能在 Windows 上的 .Net Core 3.0(或 3.1)应用程序中工作。我们发现 HTTPS_PROXY 和 HTTP_PROXY 变​​量按预期识别和处理,但默认代理似乎不支持 NO_PROXY 变​​量。这是示例代码:

 HttpClient client = new HttpClient();
 IWebProxy myProxy = HttpClient.DefaultProxy;
 Uri target = new Uri(args[0]);
 Uri proxy = myProxy.GetProxy(target);
 Console.WriteLine($"Target proxy for {target} is {proxy} {myProxy.IsBypassed(target)}");
Run Code Online (Sandbox Code Playgroud)

如果我从 Powershell 运行它:

if (-not $env:path.Contains('c:\data\src')) {
    $env:path = "$env:Path;C:\data\src\Local\DefaultProxy\bin\Debug\netcoreapp3.0"
}
$env:HTTPS_PROXY = 'http://10.11.10.10'
$env:NO_PROXY = '*'
DefaultProxy https://www.contoso.com
Run Code Online (Sandbox Code Playgroud)

我得到:https://www.contoso.com/ 的目标代理是http://10.11.10.10/ False

我希望得到空白和真实。

我应该更改什么才能使用 NO_PROXY 从默认代理中排除域?

c# http-proxy dotnet-httpclient .net-core-3.0

4
推荐指数
1
解决办法
1859
查看次数

如何使用 IHttpClientFactory 在 Blazor 服务器中配置 HttpClient 基地址

我正在尝试HttpClient在使用的Blazor服务器中配置的基地址,IHttpClientFactory但出现运行时异常:

    services.AddHttpClient("ApiClient", (provider, client) =>
    {
        var uriHelper = provider.GetRequiredService<NavigationManager>();
        client.BaseAddress = new Uri(uriHelper.BaseUri);
    });
Run Code Online (Sandbox Code Playgroud)
System.InvalidOperationException: 'Cannot resolve scoped service 'Microsoft.AspNetCore.Components.NavigationManager' from root provider.'
Run Code Online (Sandbox Code Playgroud)

异常截图

有谁知道这里可能是什么问题?

dotnet-httpclient .net-core blazor httpclientfactory blazor-server-side

4
推荐指数
1
解决办法
2787
查看次数