标签: dotnet-httpclient

如何在 .NET Framework 4.5 应用程序/网站中使用 HttpClient?

基于这里的答案: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)

asp.net http razor asp.net-4.5 dotnet-httpclient

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

cURL发布到HTTPCLient C#

我想将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)

c# curl dotnet-httpclient

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

下载时 HttpClient 未写入流

目前我正在实施一种使用 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 …

c# http stream dotnet-httpclient win-universal-app

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

在 HttpClient 中覆盖主机

我正在使用 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 标头?

c# dotnet-httpclient

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

.NET HttpClient - 远程主机强行关闭现有连接

我从 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)

c# asp.net-mvc dotnet-httpclient

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

HttpClient 在服务器上启用缓存

我正在尝试启用 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)

.net caching asp.net-web-api dotnet-httpclient

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

.Net HttpClient 无效的 URI:Uri 字符串太长

以下代码用于通过 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)

.net multipartform-data http-post dotnet-httpclient

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

在 C# 中使用 Web 服务:删除 Task.Wait()

我正在尝试使用 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)

c# task-parallel-library async-await dotnet-httpclient

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

向所有 HTTP 客户端添加 HTTP 消息处理程序

我有一个名为 的 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)

c# dotnet-httpclient .net-core asp.net-core

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

未通过 DI 传递 HttpClient 属性

我正在开发一个 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

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