基于这里的答案:How can Iretrieve and parse just the html returned from an URL?
...我尝试首先添加基于此处找到的代码:http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.aspx
...即将其添加到 \App_Code\Functions.cshtml:
@functions
{
public static string GetUrlHtml(string dynamicUrl)
{
HttpClient client = new HttpClient();
string body = await client.GetStringAsync(dynamicUrl);
// parse it using HTML Agility Pack? (http://htmlagilitypack.codeplex.com/)
}
}
Run Code Online (Sandbox Code Playgroud)
HttpClient 无法识别,并且不提供“解析”上下文菜单项。输入后,Intellisense 不向我提供“Http”:
@using System.Net.
Run Code Online (Sandbox Code Playgroud)
HttpClient 真的对我不可用吗?如果可以的话,我能得到什么作为安慰奖呢?我最好的选择是像这样使用 WebClient:
WebClient wc = new WebClient();
string body = wc.DownloadString(dynamicUrl);
// parse it with html agility pack
Run Code Online (Sandbox Code Playgroud)
...或者,如https://web.archive.org/web/20211020001935/https://www.4guysfromrolla.com/articles/011211-1.aspx#postadlink所示,我可以使用 webGet 类HTML 敏捷包:
var webGet = new HtmlWeb(); …Run Code Online (Sandbox Code Playgroud) 我想将File发布到PushBullet API服务
在API的信息站点中显示了一个示例
curl -i https://api.pushbullet.com/api/pushes \
-u API_KEY:
-F device_iden=u1qSJddxeKwOGuGW
-F type=file
-F file=@test.txt
Run Code Online (Sandbox Code Playgroud)
而我正试图用C#中的HttpClient来做
我知道如何使用Httpclient发布文件,使用MultipartFormDataContent,但是如何将device_iden和类型信息添加到客户端?
我正在使用它
using (var content = new MultipartFormDataContent())
{
try
{
content.Add(new StreamContent(new FileStream(pathFile, FileMode.Open, FileAccess.Read)));
var resp = wc.PostAsync(new Uri(baseUri, "api/pushes"), content);
}
catch (Exception)
{
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
[[新增]]
使用CURL和fiddler这将是POST
POST http://\/ HTTP/1.1
Authorization: Basic d45YQkxueWswSmxQRTYFjc1deUzNo8UtueVZpaktIZm34anVqdU9NZerWYmFlOp==
User-Agent: curl/7.33.0
Host: \
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 787
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------886f3981539a91b3
--------------------------886f3981539a91b3
Content-Disposition: form-data; name="device_iden"
ujuOMfjVbaedjz7O3P0Jl6
--------------------------886f3981539a91b3
Content-Disposition: form-data; name="type"
file
--------------------------886f3981539a91b3 …Run Code Online (Sandbox Code Playgroud) 目前我正在实施一种使用 HttpClient 报告进度的方法,因为我们与 .NET4 WPF 和 Windows 通用应用程序共享代码,我们使用来自 NuGet 的 Microsoft HTTP 客户端库。这个想法是将目标文件流包装在 a 中CountingInputStream并在那里报告进度:
public override void Write(byte[] buffer, int offset, int count)
{
_stream.Write(buffer, offset, count);
_bytesRead += count;
_progress.Report(_bytesRead);
if (_cancellationToken.IsCancellationRequested)
{
_cancellationToken.ThrowIfCancellationRequested();
}
}
Run Code Online (Sandbox Code Playgroud)
然后我发送我的请求: HttpResponseMessage httpResponseMessage = AsyncHelpers.RunSync(() => _httpClient.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseHeadersRead, cancellationToken));
之后,我打开文件流,然后复制内容流。响应具有正确的标头:
Content-Length: 213334
Content-Type: application/octet-stream; charset=UTF-8
Content-Disposition: attachment; filename="Bondi Beach.jpg"; filename*=UTF-8''Bondi%20Beach.jpg
using(Stream fileStream = new CountingInputStream(storage.Open(downloadRequest.TargetPath, FileMode.Create), downloadRequest.Progress, cancellationToken )) {
await HttpHeaderResponseMessage.Content.CopyToAsync(fileStream);
}
Run Code Online (Sandbox Code Playgroud)
问题是StreamContent只有在下载完成后才开始写入文件流。当它开始编写进度报告时,它工作正常。
我已经尝试过不同的方法,例如:
ReadAsStreamAsync 然后将响应流复制到文件流ReadAsStreamAsync …我正在使用 HttpClient 但它在 DNS 解析方面存在问题(它为此使用同步方法)所以我使用另一个库进行 DNS 查询,现在我正在尝试通过 IP 获取自定义 url,但我需要替换 Host 标头. 例如,我有 url http://fb.com,但我需要将http://1.1.1.1主机设置为 fb.com 我已经尝试过:
_req = new HttpRequestMessage(HttpMethod.Get, newUri.ToString());
_req.Headers.Host = uri.Host;
_httpClient.DefaultRequestHeaders.Host = uri.Host;
Run Code Online (Sandbox Code Playgroud)
但这不起作用。有没有办法像在 HttpWebRequest 中一样设置自己的 Host 标头?
我从 ASP.NET MVC 控制器调用了这段代码:
protected string PostData(string url, ByteArrayContent content)
{
using (var client = new HttpClient())
{
client.Timeout = TimeSpan.FromDays(1);
return client.PostAsync(url, content).Result.Content.ReadAsStringAsync().Result;
}
}
Run Code Online (Sandbox Code Playgroud)
如果我将数据发布到需要一些时间来执行的 REST 服务,我会收到此错误:
System.AggregateException: One or more errors occurred. ---> System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. ---> System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. ---> System.Net.Sockets.SocketException: …Run Code Online (Sandbox Code Playgroud) 我正在尝试启用 System.Net.HttpClient 的客户端缓存。我在http://localhost:83/api/test有一个端点,它需要 1 秒的时间来响应并将缓存标头发回。
如果我有这个代码
static async Task MainAsync()
{
var client = new HttpClient(new WebRequestHandler { CachePolicy = new HttpRequestCachePolicy() }) { BaseAddress = new Uri("http://localhost:83/api/") };
for (int i = 0; i < 20; i++)
{
var response = await client.GetAsync("test");
var res = await response.Content.ReadAsStringAsync();
Console.WriteLine(res);
}
}
Run Code Online (Sandbox Code Playgroud)
执行需要一秒钟。
如果我将相同的代码放入 api 控制器
static HttpClient client = new HttpClient(new WebRequestHandler {CachePolicy = new HttpRequestCachePolicy() }) { BaseAddress = new Uri("http://localhost:83/api/") };
public async Task<string> Get() …Run Code Online (Sandbox Code Playgroud) 以下代码用于通过 pardot api 发送电子邮件。
if (ConfigurationManager.AppSettings.Count > 0)
{
uri = ConfigurationManager.AppSettings["PardotURI"].ToString() + "email/version/4/do/send/prospect_email/" + email;
uri += "?user_key=" + ConfigurationManager.AppSettings["PardotUserKey"].ToString();
uri += "&api_key=" + GetAPIKey() + "&campaign_id=" + GetPardotCampaign("Capis News");
uri += "&from_email=" + ConfigurationManager.AppSettings["FromEmail"].ToString();
uri += "&from_name=" + ConfigurationManager.AppSettings["FromName"].ToString();
uri += "&name=FlyNews - " + DateTime.Now.ToString("MM/dd/yyy h:mm tt");
uri += "&subject=CAPIS: Client Holdings News " + DateTime.Today.ToString("MM/dd/yyyy");
}
try
{
MultipartFormDataContent data = new MultipartFormDataContent();
data.Add(new StringContent(htmlContent), "html_content");
data.Add(new StringContent(textContent), "text_content");
await client.PostAsync(uri, data);
client.Dispose();
}
catch(Exception ex) …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 Web 服务。它是一种基于 XML 的服务。我的意思是 XML 格式的响应。代码工作正常。但是,我不想使用 task.Wait()。请让我知道如何用 async/await 替换它。
下面是我的代码:
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace ConsoleApp6
{
class Program
{
static void Main(string[] args)
{
Program obj = new Program();
var result = obj.GetData().Result;
}
public async Task<string> GetData()
{
string url =
"https://test.net/info.php?akey=abcd&skey=xyz";
HttpClient client = new HttpClient();
HttpResponseMessage response = client.GetAsync(url).Result;
var responseValue = string.Empty;
if (response != null)
{
Task task = response.Content.ReadAsStreamAsync().ContinueWith(t =>
{
var stream = t.Result;
using (var reader …Run Code Online (Sandbox Code Playgroud) 我有一个名为 的 HTTP 消息处理程序AddHeadersHandler,它扩展了System.Net.Http.DelegatingHandler,我需要将它添加到所有当前和未来的HttpClient实例中,包括类型化、命名和非命名客户端。
我知道我可以.AddHttpMessageHandler<AddHeadersHandler>()为特定客户端添加一个处理程序,但是如何将它添加到所有客户端?
// AddHeadersHandler.cs
public class AddHeadersHandler: DelegatingHandler
{
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
request.Headers.TryAddWithoutValidation("X-Correlation-Id", Guid.NewGuid.ToString());
return base.SendAsync(request, cancellationToken);
}
}
Run Code Online (Sandbox Code Playgroud)
// Startup.cs
services
.AddHttpContextAccessor()
.AddTransient<AddHeadersHandler>();
services
.AddHttpClient<MyClient>()
.AddHttpMessageHandler<AddHeadersHandler>(); // I don't want to specify this for each client.
Run Code Online (Sandbox Code Playgroud)
// MyClient.cs
public class MyClient
{
public HttpClient HttpClient { get; }
public MyClient(HttpClient httpClient)
{
HttpClient = httpClient;
}
public async Task GetTest()
{
await HttpClient.GetAsync("https://localhost:5001/test"); …Run Code Online (Sandbox Code Playgroud) 我正在开发一个 ASP.NET Core 5.0 项目,该项目具有访问 API 的服务。根据下面的代码,我希望提供给 ToornamentService 的构造函数的 HttpClient 包含声明的 BaseAddress 和 API 密钥标头。
但是,在调试时,我注意到 HttpClient 从来没有这些。BaseAdress 为空,并且缺少标头。我尝试使用 IHttpClientFactory 而不是类型化的客户端,但最终得到相同的结果。
我究竟做错了什么?
配置服务方法:
public void ConfigureServices(IServiceCollection services)
{
//Omitted for brevity
services.AddHttpClient<ToornamentService>(c =>
{
c.BaseAddress = new Uri("https://api.toornament.com/");
c.DefaultRequestHeaders.Add("X-Api-Key", Configuration["Toornament:ApiKey"]);
});
services.AddTransient<ToornamentService>();
}
Run Code Online (Sandbox Code Playgroud)
ToornamentService 类:
public ToornamentService(HttpClient client)
{
Client = client; // client.BaseAddress here is null
}
Run Code Online (Sandbox Code Playgroud) c# dependency-injection dotnet-httpclient asp.net-core .net-5
c# ×7
.net ×2
asp.net-core ×2
http ×2
.net-5 ×1
.net-core ×1
asp.net ×1
asp.net-4.5 ×1
asp.net-mvc ×1
async-await ×1
caching ×1
curl ×1
http-post ×1
razor ×1
stream ×1