我们发现一个问题,即客户访问我们的 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 …
我的服务器上有多个 IP,并且想在使用 HttpClient 类从 API 获取/发布数据时选择使用其中一个。(或者甚至同时发送请求,但使用 2 个 IP,而不仅仅是一个)
我已经看到一些使用 HttpWebRequest (此处)的示例,这些示例利用委托,但我想继续使用 HttpClient 实现。
我正在尝试从我的 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) 这是一个完全有效的示例(复制/粘贴它并尝试一下,只需获取 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 秒,然后返回响应。
我已经设置了这样的策略( …
我认为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) 嗨,我正在尝试模拟 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) 我正在寻找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) 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) 我们正在尝试让代理功能在 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 从默认代理中排除域?
我正在尝试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
c# ×9
polly ×2
unit-testing ×2
.net-core ×1
asynchronous ×1
blazor ×1
csrf ×1
http-proxy ×1
iis ×1
moq ×1
retry-logic ×1
timeout ×1
wpf ×1