需要帮助将我的RestSharp代码转换为使用HttpClient

时间:2019-01-23 21:02:32

标签: c# api restsharp dotnet-httpclient

由于我需要将此C#dll转换为要从Visual Basic 6调用的tlp文件,因此需要避免使用外部依赖项。我已经使用RestSharp通过执行以下操作来使用WebAPI:

using RestSharp;
using Newtonsoft.Json;

..

public string GetToken (string Key, string Password) {

  var client = new RestClient (BaseUrl + "auth/GetToken");
  var request = new RestRequest (Method.POST);
  request.AddHeader ("cache-control", "no-cache");
  request.AddHeader ("Content-Type", "application/json");
  Dictionary<string, string> data = new Dictionary<string, string> {
    { "APIKey", Key },
    { "APIPassword", Password }
};
var dataJSON = JsonConvert.SerializeObject (data);
request.AddParameter ("undefined", dataJSON, ParameterType.RequestBody);

IRestResponse response = client.Execute (request);

GetTokenResults g = JsonConvert.DeserializeObject<GetTokenResults> (response.Content); 

return g.Token;
}

其中,GetTokenResults是一个结构,其中包含字符串Token的声明。我想在不使用RestSharp的情况下实现相同的功能。这是我失败的尝试:

using System.Net.Http;
using System.Net.Http.Headers;

..

public async void GetToken (string Key, string Password) {

  var client = new HttpClient ( );
  client.DefaultRequestHeaders.Accept.Clear ( );
  client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue ("application/json"));
  client.BaseAddress = new Uri (BaseUrl + "auth/GetToken");

  Dictionary<string, string> data = new Dictionary<string, string> {
  { "APIKey", Key },
  { "APIPassword", Password }
};
  var dataJSON = JsonConvert.SerializeObject (data);

  var content = new StringContent (dataJSON, Encoding.UTF8, "application/json");

  var response = await client.PostAsync ("", content);

}

我不清楚如何使用HttpClient达到与之前使用RestSharp相同的结果(发送API密钥和密码,以字符串形式返回令牌)。任何能将我指向正确方向的东西,我们将不胜感激!

2 个答案:

答案 0 :(得分:0)

我认为您在方法PostAsync中缺少第一个参数,即requestUri = Client.BaseAddress(请参阅下面的实现)。

请先尝试一下,如果没有用,请阅读以下内容。我有一个不同的实现,我将client.BaseAddress作为第一个参数传递,并将我的内容作为ByteArrayContent传递。就我而言,我必须将我的内容作为代码的“ application / x-www-form-urlencoded”摘录传递:

        var buffer = Encoding.UTF8.GetBytes(content);
        var byteContent = new ByteArrayContent(buffer);
        //as I can't send JSON, probably, you can skip as it's already JSON
        byteContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded");  
       //requestUri=client.BaseAddress          
        await client.PostAsync(requestUri, byteContent).ConfigureAwait(false); 

我们的需求有所不同,但我认为您非常接近。如果没有帮助,请写信给我,我将分享我的代码。阅读评论后,我想分享我如何制作HttpClient。代码如下:

 using (var client = CreateMailClientForPOST($"{BaseUrl}/"))
        {
           //removed code, you can call above code as method like
           var response= await client.DoThingAsAsync($"{client.BaseAddress}, content").ConfigureAwait(false);
        }

protected HttpClient CreateMailClientForPOST(string resource)
    {
        var handler = new HttpClientHandler();
        if (handler.SupportsAutomaticDecompression)
        {
            handler.AutomaticDecompression = System.Net.DecompressionMethods.GZip | System.Net.DecompressionMethods.Deflate;
        }

        var client = new HttpClient(handler)
        {

            BaseAddress = new Uri($"https://api.address.com/rest/{resource}")
        };
        return client;
    }

答案 1 :(得分:0)

我认为您被this issue吓了一跳。简而言之,client.BaseAddress中的URI在其末尾需要一个斜杠。

但是,我不会简单地添加它,我会考虑做一些不同的事情。假设您要向其附加BaseUrl,那么您的"auth/GetToken"可能已经有一个斜杠。我会这样:

client.BaseAddress = new Uri(BaseUrl);
...
var response = await client.PostAsync("auth/GetToken", content);

如您所见,HttpClient非常适合您的代码设置方式,即您有一个带有尾斜杠的“基本”地址,并且您想为特定的调用附加到该地址。 / p>

这应该使您摆脱困境。您需要解决的下一件事是反序列化JSON响应,以便您可以从中获取令牌。与response.Content不是HttpClient世界中的字符串一样,它与您在RestSharp中的操作类似,因此您还需要执行以下步骤:

var json = await response.Content.ReadAsStringAsync();
GetTokenResults g = JsonConvert.DeserializeObject<GetTokenResults>(json);
return g.Token;

您需要做的最后一件事就是将方法签名更改为:

public async Task<string> GetTokenAsync

最后一点:您现在处于异步世界,这是一件好事,但是您需要知道如何正确使用它,否则可能会遇到死锁和其他神秘的错误。简而言之,通过在调用堆栈中的任意位置调用.Result.Wait()don't block on async code。这是迄今为止人们最常见的错误。一直使用async/await