使用 HttpWebRequest,我可以调用 XDocument.Save()直接写入请求流:
XDocument doc = ...;
var request = (HttpWebRequest)WebCreate.Create(uri);
request.method = "POST";
Stream requestStream = request.GetRequestStream();
doc.Save(requestStream);
Run Code Online (Sandbox Code Playgroud)
是否可以用 做同样的事情HttpClient?直接的方法是
XDocument doc = ...;
Stream stream = new MemoryStream();
doc.Save(stream);
var content = new System.Net.Http.StreamContent(stream);
var client = new HttpClient();
client.Post(uri, content);
Run Code Online (Sandbox Code Playgroud)
但这会在 中创建另一个副本。XDocumentMemoryStream
我刚刚在 winforms 应用程序中发现的东西
我的应用程序对 Web Api 服务进行 http 调用,如下所示
HttpClient _client = new HttpClient();
_client.Timeout = new TimeSpan(0, 3, 0);
_client.BaseAddress = new Uri("http://Myserver/MyApp");
_client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = _client.PostAsJsonAsync("api/Addin", newObject).Result;
Run Code Online (Sandbox Code Playgroud)
没什么特别的,但是一旦你通过 nuget 安装 Newtonsoft.Json (V6.0.3)
突然我在 HttpResponseMessage 代码行上收到 stackOverflow 错误。删除Newtonsoft,问题就解决了。
问题是我要使用该库在表单中的其他位置序列化/反序列化数据
我的解决方法是使用不同的库,我只是使用 System.Runtime.Serialization.Json;但这仍然很奇怪,不是吗?
我还应该补充一点,这是 dotnet v4.0(不是 4.5),我的应用程序是一个在 MsWord 中作为附加组件运行的 VSTO COM 对象
我怀疑 Newtonsoft 可能存在错误
根据评论和更多测试完全更新。
我正在使用 PostMan (Chrome 扩展)通过 HTTP POST 调用网络服务。通过 C# 执行相同操作的速度较慢。为什么,我不知道。也许没什么可做的。
浏览器(PostMan)的响应时间每次约为 70 毫秒。我用 C# 做了不同的版本:
HttpClient(甚至重复使用相同的 HttpClient,连续调用 2 次,只是按照注释中的建议测量第二次调用的时间)。时间最好为 150 毫秒,通常为 170 毫秒。这实际上是第二次调用,不包括创建实例。只需 POST 和 DL 答案即可。在上传(POST 正文)和下载响应时使用等待,即使这对于此测试来说确实无关紧要。WebClient,不包括初始化客户端,只是post请求和响应,没有解析,只是从字节到字符串的转换,160ms。HttpWebRequest(ServiceStack v4的JsonServiceClient):大致相同。我已经尝试过包括
System.Net.ServicePointManager.Expect100Continue = false;
System.Net.ServicePointManager.MaxServicePoints = 200;
Run Code Online (Sandbox Code Playgroud)
但结果是一样的。
那么答案是否只是 Chrome(Postman 构建于其上)比 .NET 优化得更好,还是有什么可以做的?
PS:是的,我知道这可能看起来更像是讨论而不是问答,但我正在寻找答案,所以从这个意义上说,这是一个问题。
HttpClient我正在为我的 Web 应用程序正在通信的每个不同的 API创建一个实例。
我想使用依赖注入和SimpleInjector来注入HttpClient业务类。例如,我有ITwitterBusiness和IInstagramBusiness,并且它们都HttpClient在其构造函数中接受。
使用依赖注入注册多个相同类型的对象时,最佳实践是什么?
我很确定问题的一部分可能是我的设计,但这里有一些想法。
我的第一个想法是在 DI 注册中使用 delegate
container.Register<ITwitterBusiness>(() => new TwitterBusiness(httpClientTwitter));
Run Code Online (Sandbox Code Playgroud)
看起来很简单,但我不知道这种方法是否有任何不良副作用,例如使 SimpleInjector 运行速度变慢或者我是否破坏了某些设计模式。
我的第二个想法是使用基于上下文的注入 http://simpleinjector.readthedocs.io/en/latest/advanced.html#context-based-injection
我相信这将允许我将某个 HttpClient 实例注入某个类。仍然不确定这是如何工作的。
我很好奇是否可以纯粹通过设计来解决这个问题。例如通过创建虚拟类。我只是还没有找到任何好的例子,但是如果我理解正确,那么我可以创建虚拟类,例如HttpClientTwitter继承HttpClient,这样我就可以摆脱不明确的注册。
谢谢!
c# dependency-injection ambiguous simple-injector dotnet-httpclient
我制作了一个控制台应用程序,它基本上对我的服务器执行大量请求。每个用户 10-15000 个请求。
所以我编写了使用 .NET 的 HTTP 客户端库的代码:
public async Task<string> DoRequest(string token)
{
var request = new HttpRequestMessage(HttpMethod.Post, "mysite.com");
string requestXML = "my xml request goes her...";
request.Content = new StringContent(requestXML, Encoding.UTF8, "text/xml");
var response = await httpClient.SendAsync(request);
return await response.Content.ReadAsStringAsync();
}
Run Code Online (Sandbox Code Playgroud)
所以现在我尝试每 1 秒执行尽可能多的 HTTP 请求...我不知道这个上限是多少,所以我使用并行 for 循环来加速:
Parallel.For(0,list.Count(),items=>{
DoRequest(item.Token);
});
Run Code Online (Sandbox Code Playgroud)
但我对代码的速度以及请求的发出方式不太满意......
有什么方法可以加快速度,每 1 秒最多可以处理 10-100 个请求?或者最大限制是多少?
有人可以帮我吗 ?
PS,我只创建了一个 httpclient 类的实例,因为我读到,只创建一个实例是一种很好的做法,因为每次创建该类的新对象时,连接都会关闭,这不是我们想要的不是吗?
我有一个如下所示的卷曲请求:
curl -i -XPOST 'http://my_url:port/write?db=myDb' -u user:xxxxx --data-binary 'FieldName,host=M.233 value=52.666 timestamp'
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用 HttpClient 发布此请求。我不确定应该如何称呼它。这就是我试图做的:
public async void TestHttpClient()
{
var client = new HttpClient();
var credentials = Encoding.ASCII.GetBytes("user:xxxxx");
var header = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(credentials));
client.DefaultRequestHeaders.Authorization = header;
client.BaseAddress = new Uri("http://my_url:port/write?db=myDb");
var result = await client.PostAsync(..);
}
Run Code Online (Sandbox Code Playgroud)
我应该为 PostAsync() 编写哪些参数?
如何从curl 转换--data-binary为FieldName,host=M.233 value=52.666 timestampHttpClient?
我想向在 IIS 服务器下运行的客户端 .NET 应用程序添加相互身份验证(它是一个调用另一个 Web 服务的 Web 服务)。客户端应用程序从文件加载客户端证书,并且在我的开发计算机上使用以下代码可以正常工作(我尝试使用 .NET 4.6.2 的 Windows 7 和 Windows 10):
var handler = new WebRequestHandler();
var certificate = new X509Certificate2(clientCertPath); -- PFX file with client cert and private key
handler.ClientCertificates.Add(certificate);
handler.AuthenticationLevel = AuthenticationLevel.MutualAuthRequired;
client = new HttpClient(handler);
Run Code Online (Sandbox Code Playgroud)
但是,当将此代码部署到生产 Windows 2016 Server 计算机时,应用程序会抛出异常The request was aborted: Could not create SSL/TLS secure channel.
我启用了跟踪,System.Net这是我在日志中看到的
SecureChannel#66407304 - Certificate is of type X509Certificate2 and contains the private key.
AcquireCredentialsHandle(package = Microsoft Unified Security Protocol …Run Code Online (Sandbox Code Playgroud) c# iis client-certificates dotnet-httpclient mutual-authentication
我有一个同时接收多个请求的网络服务。对于每个请求,我需要调用另一个网络服务(身份验证)。问题是,如果同时发生多个(>20)请求,响应时间会突然变得更糟。
我制作了一个示例来演示该问题:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace CallTest
{
public class Program
{
private static readonly HttpClient _httpClient = new HttpClient(new HttpClientHandler { Proxy = null, UseProxy = false });
static void Main(string[] args)
{
ServicePointManager.DefaultConnectionLimit = 100;
ServicePointManager.Expect100Continue = false;
// warmup
CallSomeWebsite().GetAwaiter().GetResult();
CallSomeWebsite().GetAwaiter().GetResult();
RunSequentiell().GetAwaiter().GetResult();
RunParallel().GetAwaiter().GetResult();
}
private static async Task RunParallel()
{
var tasks = new List<Task>();
for (var i = 0; i < 300; i++)
{
tasks.Add(CallSomeWebsite());
}
await …Run Code Online (Sandbox Code Playgroud) 我一直在开发一个确定网页信息的应用程序。其中的组成部分之一涉及向 URL 发出 HTTP GET 请求、抓取 HTML 并对其进行分析。这对于我向它抛出的每个 URL 都运行良好,除了一个......
罪魁祸首是 .NET HttpClient,它似乎总是在请求问题域内的任何 URL 时超时。然而,使用浏览器请求的相同 URL 在几毫秒内就会返回内容。标题似乎没有什么异常。
增加超时只会导致爆炸需要更长的时间。我已经尝试了几分钟,结果相同。我尝试过各种方法,例如将用户代理字符串设置为 Chrome 的字符串,但没有成功。
有问题的域是:http://careers.adidas-group.com 请注意,同一站点也在https://careers.adidas-group.com上运行在 HTTPS 上(它具有有效的证书)。使用任一协议都会导致相同的错误。
我可以使用一个简单的 C# 控制台应用程序来显示该问题,如下所示:
static void Main(string[] args)
{
string url = "http://careers.adidas-group.com";
var client = new HttpClient
{
Timeout = TimeSpan.FromSeconds(10)
};
using (var message = new HttpRequestMessage(HttpMethod.Get, url))
{
using (var httpResponse = Task.Run(() => client.SendAsync(message)).Result)
{
Console.WriteLine("{0}: {1}", httpResponse.StatusCode, httpResponse.ReasonPhrase);
}
}
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
请注意,在上面的示例中,我将超时设置为 10 秒,只是为了加快解决问题的速度 - 但是,增加超时并没有什么区别。
具有不同 …
我正在使用HttpClient通过传递标头进行 POST 调用,但在某些时候我收到如下错误:
Request headers must contain only ASCII characters.
Run Code Online (Sandbox Code Playgroud)
使用堆栈跟踪:
at System.Net.Http.HttpConnection.WriteStringAsync(String s)
at System.Net.Http.HttpConnection.WriteHeadersAsync(HttpHeaders headers, String cookiesFromContainer)
at System.Net.Http.HttpConnection.SendAsyncCore(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithNtConnectionAuthAsync(HttpConnection connection, HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.DiagnosticsHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
public HttpWrapper(string endpoint, Func<IDictionary<string, string>> NewHeader)
{
_httpClient = new HttpClient();
_httpClient.BaseAddress = new Uri(endpoint);
if (NewHeader != …Run Code Online (Sandbox Code Playgroud)