c# 异步 curl 请求 - 我如何访问响应?

Posted

技术标签:

【中文标题】c# 异步 curl 请求 - 我如何访问响应?【英文标题】:c# Async curl request - how do I access the response? 【发布时间】:2019-07-03 07:55:48 【问题描述】:

我正在尝试将来自 Jira API 的 curl 请求示例转换为 C# 请求。

这是 JIRA 提供的原始 Curl Request 示例:

curl \
   -D- \
   -u charlie:charlie \
   -X GET \
   -H "Content-Type: application/json" \
   http://localhost:8080/rest/api/2/search?jql=assignee=charlie

我已将其翻译成以下 JIRA 代码:

但是响应行不起作用 - 因为我拼凑了一些示例并且有点卡住了!

var myTask = curlRequestAsync(); // call your method which will return control once it hits await

string result = myTask.Result();
// .Result isn't defined - but I'm not sure how to access the response from my request!

任何帮助将不胜感激,因为我真的被困住了!

完整示例:

public partial class WebForm2 : System.Web.UI.Page


    protected void Page_Load(object sender, EventArgs e)
    

        var myTask = curlRequestAsync(); // call your method which will return control once it hits await

        string result = myTask.Result();
        // wait for the task to complete to continue

    

    protected async System.Threading.Tasks.Task curlRequestAsync()
    
        try
        
            using (var httpClient = new HttpClient())
            
                using (var request = new HttpRequestMessage(new HttpMethod("GET"), "http://myurl.co.uk/rest/api/2/search?jql=assignee=bob"))
                
                    var base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes("username:password"));
                    request.Headers.TryAddWithoutValidation("Authorization", $"Basic base64authorization");

                    var result = await httpClient.SendAsync(request);

                    return result;
                
            
        
        catch (Exception ex)
        
            error.InnerText = ex.Message;
        
    

【问题讨论】:

你可能应该使用var result = await curlRequestAsync(); 【参考方案1】:

你应该返回Task<System.Net.Http.HttpResponseMessage>

protected async System.Threading.Tasks.Task<HttpResponseMessage> curlRequestAsync()

    try
    
        using (var httpClient = new HttpClient())
        
            using (var request = new HttpRequestMessage(new HttpMethod("GET"), "http://myurl.co.uk/rest/api/2/search?jql=assignee=bob"))
            
                var base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes("username:password"));
                request.Headers.TryAddWithoutValidation("Authorization", $"Basic base64authorization");

                var result = await httpClient.SendAsync(request);

                return result;
            
        
    
    catch (Exception ex)
    
         error.InnerText = ex.Message;
    

之后您可以访问任务的响应:

var myTask = curlRequestAsync();

var result = myTask.Result.Content.ReadAsStringAsync().Result;

【讨论】:

我会避免调用 .Result。最好调用 GetAwaiter.GetResult() 然后得到原始异常而不是聚合。 @RalphWillgoss 是的,你是对的。而且代码是两次“结果”相当难看。但我希望它会从异步代码中调用,结果不会被使用。【参考方案2】:

由于 async 关键字,您的方法签名,如“编译器所见”,在方法的范围内被转换:

protected async Task Foo()

会变成

protected void Foo(); 

要返回一个带有async关键字的值,你应该使用这个签名:

protected async Task<T> Foo()

导致

protected T Foo()

至于调用者,签名保持不变。

Task 上,Result 没有定义,因为它本质上没有任务的返回值。另一方面,Task&lt;T&gt;Result

因此,为了获得“结果”,(Result 未在 Task 上定义(Wait 是),您应该使用 Task&lt;T&gt;,在其上定义了 Result

在您的情况下,您应该将签名更改为:

protected async System.Threading.Tasks.Task<WhatEverTypeYouAreReturning> curlRequestAsync()

如果您处于异步范围内,您现在将能够获得 Resultawait 调用。后者是首选,因为它会使您的方法保持异步,这对资源的使用有一些好处。

【讨论】:

以上是关于c# 异步 curl 请求 - 我如何访问响应?的主要内容,如果未能解决你的问题,请参考以下文章

将 CURL 请求转换为 C# 以访问 Snipcart API 返回 401 Unauthorized

如何在 PHP 中发出异步 HTTP 请求

如何在php中获取curl请求的请求头信息及相应头信息

C# 使用 NetworkStream 进行异步读写

怎么判断curl调用接口返回成功:响应码

如何在fetch then / response函数中访问请求对象