C# HttpClient 通用 SendAysnc 不起作用

Posted

技术标签:

【中文标题】C# HttpClient 通用 SendAysnc 不起作用【英文标题】:C# HttpClient Generic SendAysnc not working 【发布时间】:2020-08-25 05:33:19 【问题描述】:

我是 C# 中编写泛型方法的新手,我正在尝试在我的 C# 项目中创建一个泛型 SendAsync 方法。代码如下。

HttpClientHelper.cs

public static async Task<T2t> ExecuteRequest<T1,T2>(T2 request, string url)

    Uri requestUri = new Uri(url);
    string payload = JsonConvert.SerializeObject(request);
    HttpContent httpContent = new StringContent(payload, "application/json");

    HttpRequestMessage requestMessage = new HttpRequestMessage
    
        Method = HttpMethod.Post,
        RequestUri = requestUri,
        Content = httpContent
    ;

    return await SendUriAsync<T2>(requestMessage);


public static async Task<T> SendUriAsync<T>(HttpRequestMessage requestMessage)

   
    string clint_id = "1234";
    
      var clineCred = Encoding.UTF8.GetBytes($"client_id");
        
        using(var result = await client.SendAsync(requestMessage))
        
            result.EnsureSuccessStatusCode();
            var response = await result.Content.ReadAsStringAsync();
            
            if(result.IsSuccessStatusCode && response != null)
            
                return JsonConvert.DeserializeObject<T>(response);
            
            else
            
                return null;
            
                
 

这是调用这些方法的控制器类:

CarSalesController.cs

string thirdpartyUrl = "someurl";
var responseObject = await HttpClientHelper.ExecuteRequest<CarObject, string>(requestObject, thirdpartyUrl);

我在 HttpClientHelper 类中遇到错误。错误是:

ResponseStatusCode 不表示成功。 StatusCode:401 - 未授权

但是当我使用邮递员时,相同的 API 效果很好。他是cURL

curl --location --request GET 'someurl' --header 'client_id:1234' --header '授权:基本 asdf' --header '内容类型:应用程序/json' --data-raw ' “数据1”:“一些数据1”, “数据2”:“一些数据2” '

我的代码有什么问题?

【问题讨论】:

尝试:CreateRequest @jdweng 此更改无效 不应该序列化(而不是反序列化)CreateRequest方法最后一行的对象吗? 你反序列化响应两次 @MikaKarjunen 感谢您的提示。我已经相应地修改了代码 【参考方案1】:

这不是你想要做的吗?

public async Task<TOut> ExecuteRequestAsync<TIn, TOut>( TIn request, string url )

    var requestUri = new Uri( url );
    var payload = JsonConvert.SerializeObject( request );
    var httpContent = new StringContent( payload, Encoding.UTF8, "application/json" );
    var requestMessage = new HttpRequestMessage()
    
        Method = HttpMethod.Post,
        RequestUri = requestUri,
        Content = httpContent
    ;
    return await SendUriAsync<TOut>( requestMessage );


public static async Task<T> SendUriAsync<T>( HttpRequestMessage requestMessage )

    using (var client = CreateClient( 1234 ))
    
        var result = await client.SendAsync( requestMessage );
        result.EnsureSuccessStatusCode();
        var response = await result.Content.ReadAsStringAsync();
        return JsonConvert.DeserializeObject<T>( response );
    


private static HttpClient CreateClient(int clientId)

    var clientCred = Encoding.UTF8.GetBytes( clientId.ToString() );
    var auth = Convert.ToBase64String( clientCred );
    var client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue( "Basic", auth );
    client.DefaultRequestHeaders.Add( "client_id", "1234" );
    return client;

【讨论】:

谢谢。这就像一个魅力。我在做不必要的转换。但是,当我执行代码时,它在 client.SendAsync(requestMessage) 行出现错误,提示“无法从传输连接读取数据。现有连接被远程主机强行关闭”。什么可能导致这个问题。是否与 HttpClient.我正在使用 .Net 4.7.2 很高兴能提供帮助。确保 url 正确并且找到了服务。考虑尝试使用 fiddler 或任何类似工具进行测试调用。此外,您可能想添加调用“result.EnsureSuccessStatusCode();”在 client.SendAsync 之后。 我已经添加了上面的代码。但我现在得到一个不同的错误。我已经修改了问题中的代码。你能看看吗 这里。我添加了凭据和其他标头信息。您应该考虑将 HttpClient 的创建移到处理这些事情的 FactoryClass 中。 谢谢。我已经尝试了上面的代码,但我得到了一个错误。 ResponseStatus - 禁止。看起来凭据是错误的。但我提供了正确的client_Id【参考方案2】:

问题可能出在DeserializeObject。尝试使用:

response.Content.ReadAsStringAsync()

【讨论】:

在 CreateRequest() 方法中,当我将其更改为上述代码时,它显示“无法将 Task 转换为 TOut” @Learner,你不能从response反序列化你必须从一个字符串反序列化。

以上是关于C# HttpClient 通用 SendAysnc 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

通用 Windows 项目 - HttpClient 异常

通用httpclient生成方式

使用 Microsoft.HttpClient 和 HttpContentExtensions 的通用 POST 请求

C#关于HttpClient的统一配置

详解 UWP (通用 Windows 平台) 中的两种 HttpClient API

C# 中的 HttpClient 多部分表单发布