.Net Core 2.2,PutAsync,HttpContent 问题

.Net Core 2.2, PutAsync, HttpContent Question

我正在从 node with express 过渡到 .Net Core 2.2。我正在尝试创建一个放置请求以将更新推送到 api。我发现我可以用

创建它

var client = new HttpClient(); client.PutAsync(url, httpContent)

我的第一个问题是,如何创建 httpContent?通常在这种情况下我会创建一个 JSON 对象,但当然这在这里不起作用。

我的第二个问题是,我使用的是 .Net Core 2.2。使用 HttpClient 的方式正确还是我应该使用 Factory?

请参考以下代码片段发起post请求,同样可以实现put请求,只需将方法改为Put即可。

protected async Task<Tuple<HttpStatusCode, TOutput>> MakeRequest<TInput, TOutput>(string baseAdrress, string apiUrl, TInput data)
{
    var contentData = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json");

    var client = new HttpClient();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    client.BaseAddress = new Uri(baseAdrress);

    var response = await client.SendAsync(new HttpRequestMessage
    {
        RequestUri = new Uri(apiUrl, UriKind.Relative),
        Content = contentData,
        Method = HttpMethod.Post
    });

    if (response.StatusCode == HttpStatusCode.InternalServerError)
    {
        return Tuple.Create(HttpStatusCode.InternalServerError, default(TOutput));
    }

    var stringData = await response.Content.ReadAsStringAsync();
    var jsonData = JsonConvert.DeserializeObject<TOutput>(stringData);

    return Tuple.Create(HttpStatusCode.OK, jsonData);
}

以上代码只是使用http客户端的快速演示,在real-world中,您应该改用HttpClientFactory。您可以通过多种方式使用 HttpClientFactory read here at Microsoft Docs

直接使用HttpClient会导致M$提到的一些问题"As a first issue, while this class is disposable, using it with the using statement is not the best choice because even when you dispose HttpClient object, the underlying socket is not immediately released and can cause a serious issue named ‘sockets exhaustion’."

您可以使用以下代码片段发出 Put 请求。

 protected async Task<Tuple<Boolean, TOutput>> PutResult<TInput, TOutput>(String url, TOutput fallbackValue, TInput input)
 {
   HttpRequestMessage requestMessage = GetPutHttpRequestMessageWithSerializedContent(url, input);
   Tuple<Boolean, TOutput> result = await SendAsync(requestMessage, fallbackValue);
   return result;
 }

 private HttpRequestMessage GetPutHttpRequestMessageWithSerializedContent<TInput>(String url, TInput input)
    {
        String rawContent = JsonConvert.SerializeObject(input, JsonSerializerOptions);

        StringContent content = new StringContent(rawContent, Encoding.UTF8, "application/json");
        HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Put, url)
        {
            Content = content
        };

        return requestMessage;
    }