繁体   English   中英

重构HttpWebRequest到HttpClient?

[英]Refactor HttpWebRequest to HttpClient?

我如何将其转换为HttpClient? 我要做的是向Twitter api提交一条推文,并以Json的身份获得回复。 HttpWebRequest工作正常,但我只是想将它移植到HttpClient。 我在第二个代码示例中尝试了它,但它实际上并没有发送或接收响应。

HttpWebRequest request = null;
WebResponse response = null;
string responseCode = String.Empty;
try
{
    string postBody = "status=" + EncodingUtils.UrlEncode(status);

    request = (HttpWebRequest)HttpWebRequest.Create(resource_url);        
    request.ServicePoint.Expect100Continue = true;
    request.UseDefaultCredentials = true;
    request.PreAuthenticate = true;
    request.Credentials = CredentialCache.DefaultCredentials;
    request.ServicePoint.ConnectionLimit = 1;
    request.Headers.Add("Authorization", authHeader);
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";

    using (Stream stream = request.GetRequestStream())
    {
        using (StreamWriter writer = new StreamWriter(stream))
        {                       
            writer.Write(postBody);
        }
    }
    using (response = request.GetResponse())
    {
        response.ContentType = "application/json";
        responseCode = ((HttpWebResponse)response).StatusCode.ToString();
    }
}
catch (WebException ex)
{
    if (ex.Status != WebExceptionStatus.NameResolutionFailure)
    {
        request.Abort();
        request = null;
    }
    throw ex;
}
return responseCode;

这是我试图让它工作的原因:

private async Task<string> MakeWebRequest1(string status, string resource_url, string authHeader)
    {
        HttpClientHandler clientHandler = new HttpClientHandler();
        clientHandler.Credentials = CredentialCache.DefaultCredentials;
        clientHandler.PreAuthenticate = true;
        clientHandler.AllowAutoRedirect = true;
        string responseCode = "";
        string postBody = "status=" + EncodingUtils.UrlEncode(status);
        var request = new HttpRequestMessage()
        {
            RequestUri = new Uri(resource_url),
            Method = HttpMethod.Post,

        };
        request.Headers.Add("Authorization", authHeader);
       // request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
        request.Content = new StringContent(postBody, Encoding.UTF8,"application/x-www-form-urlencoded");//CONTENT-TYPE header

        using (HttpClient client = new HttpClient(clientHandler))
        {
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded"));
            //  Stream stuff = await client.GetStreamAsync(resource_url);
            using (HttpResponseMessage response = await client.SendAsync(request))
            {
                response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
                if(response.StatusCode == HttpStatusCode.OK)
                {
                    responseCode = "OK";
                }
            }
        }
        clientHandler.Dispose();
        return responseCode;
    }
enter code here

我试图在请求中添加另一个参数,并且它总是以未经授权的方式返回401。 我正在尝试创建一个Twitter帖子。 如果我删除了in_reply_to_status_id,那就没关系了。

data = new Dictionary<string, string> {
      ["status"] = "@username + status,
      ["in_reply_to_status_id"] = "1167588690929115136"
};

Twitter API在此处描述https://developer.twitter.com/en/docs/tweets/post-and-engage/api-reference/post-statuses-update

参考您正在使用HttpClient错误来理解为什么使用静态客户端。

static Lazy<HttpClient> client = new Lazy<HttpClient>(() => {
    HttpClientHandler clientHandler = new HttpClientHandler {
        Credentials = CredentialCache.DefaultCredentials,
        PreAuthenticate = true,
        AllowAutoRedirect = true
    };
    return new HttpClient(clientHandler);
});

private async Task<string> PostStatusRequestAsync(string status, string resource_url, string authHeader) {
    using (var request = new HttpRequestMessage(HttpMethod.Post, resource_url)) {
        request.Headers.TryAddWithoutValidation("Authorization", authHeader);
        request.Headers.Accept.Clear();
        request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        var data = new Dictionary<string, string> {
            ["status"] = status
        };

        request.Content = new FormUrlEncodedContent(data);

        using (HttpResponseMessage response = await client.Value.SendAsync(request)) {
            return response.StatusCode.ToString();
        }
    }
}

请注意FormUrlEncodedContent对请求体的使用,它将编码和连接数据以及处理mime类型头

......但它实际上并没有发送或接收响应。

确保不会将上述调用作为同步阻塞调用,例如.Result ,这可能会导致死锁。

例如,异步事件处理程序可用于进行异步调用

public async void onButtonClick(object sender, EventArgs args) {
    //Non-blocking call
    var tweetRequestCode = await PostStatusRequestAsync(TweetText, AuthUtils.GetResourceUrl(), AuthUtils.GetWebRequestHeader())); 

    //back on UI thread
    //...
}

参考Async / Await - 异步编程的最佳实践

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM