Windows.Web.Http.HttpClient类的PATCH异步请求


Answers:


84

我发现了如何做一个“定制”PATCH与上一个请求System.Net.Http.HttpClient在这里,然后用,直到我把它的工作拨弄Windows.Web.Http.HttpClient类,如下所示:

public async Task<HttpResponseMessage> PatchAsync(HttpClient client, Uri requestUri, IHttpContent iContent) {
    var method = new HttpMethod("PATCH");

    var request = new HttpRequestMessage(method, requestUri) {
        Content = iContent
    };

    HttpResponseMessage response = new HttpResponseMessage();
    // In case you want to set a timeout
    //CancellationToken cancellationToken = new CancellationTokenSource(60).Token;

    try {
         response = await client.SendRequestAsync(request);
         // If you want to use the timeout you set
         //response = await client.SendRequestAsync(request).AsTask(cancellationToken);
    } catch(TaskCanceledException e) {
        Debug.WriteLine("ERROR: " + e.ToString());
    }

    return response;
}

而不是``HttpResponseMessage response = new HttpResponseMessage(); 使用use var response = default(HttpResponseMessage); `
威尔默

54

更新:请参见下面的SSX-SL33PY的答案,以获取更好的解决方案,其作用相同。

您可以编写与扩展方法完全相同的方法,因此可以直接在HttpClient对象上调用它:

public static class HttpClientExtensions
{
   public static async Task<HttpResponseMessage> PatchAsync(this HttpClient client, Uri requestUri, HttpContent iContent)
   {
       var method = new HttpMethod("PATCH");
       var request = new HttpRequestMessage(method, requestUri)
       {
           Content = iContent
       };

       HttpResponseMessage response = new HttpResponseMessage();
       try
       {
           response = await client.SendAsync(request);
       }
       catch (TaskCanceledException e)
       {
           Debug.WriteLine("ERROR: " + e.ToString());
       }

       return response;
   }
}

用法:

var responseMessage = await httpClient.PatchAsync(new Uri("testUri"), httpContent);

您如何传递内容?
路易斯·瓦伦西亚

4
您看到第二个参数了吗?尝试这样的事情:HttpContent httpContent = new StringContent("Your JSON-String", Encoding.UTF8, "application/json");对于字符串内容。
亚历山大·帕查

如果我错了,请指正我,但是PATCH方法意味着您只能修改JSON中的特定数据。假设您仅修改产品名称,该如何修改?如果用“您的JSON-String”表示整个JSON,那么我很困惑。我尝试添加单个属性,HttpContent content = new StringContent("{\"name\":\"John Doe\"", Encoding.UTF8, "application/json");但内容未添加到请求中。
Caloyski

38

我想扩展@ alexander-pacha的答案,并建议在公共库中的某处添加以下扩展类。如果这是项目/客户/框架/ ...的通用库,那么您就必须自己制作一个库。

    public static class HttpClientExtensions
    {
        /// <summary>
        /// Send a PATCH request to the specified Uri as an asynchronous operation.
        /// </summary>
        /// 
        /// <returns>
        /// Returns <see cref="T:System.Threading.Tasks.Task`1"/>.The task object representing the asynchronous operation.
        /// </returns>
        /// <param name="client">The instantiated Http Client <see cref="HttpClient"/></param>
        /// <param name="requestUri">The Uri the request is sent to.</param>
        /// <param name="content">The HTTP request content sent to the server.</param>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="client"/> was null.</exception>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="requestUri"/> was null.</exception>
        public static Task<HttpResponseMessage> PatchAsync(this HttpClient client, string requestUri, HttpContent content)
        {
            return client.PatchAsync(CreateUri(requestUri), content);
        }

        /// <summary>
        /// Send a PATCH request to the specified Uri as an asynchronous operation.
        /// </summary>
        /// 
        /// <returns>
        /// Returns <see cref="T:System.Threading.Tasks.Task`1"/>.The task object representing the asynchronous operation.
        /// </returns>
        /// <param name="client">The instantiated Http Client <see cref="HttpClient"/></param>
        /// <param name="requestUri">The Uri the request is sent to.</param>
        /// <param name="content">The HTTP request content sent to the server.</param>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="client"/> was null.</exception>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="requestUri"/> was null.</exception>
        public static Task<HttpResponseMessage> PatchAsync(this HttpClient client, Uri requestUri, HttpContent content)
        {
            return client.PatchAsync(requestUri, content, CancellationToken.None);
        }
        /// <summary>
        /// Send a PATCH request with a cancellation token as an asynchronous operation.
        /// </summary>
        /// 
        /// <returns>
        /// Returns <see cref="T:System.Threading.Tasks.Task`1"/>.The task object representing the asynchronous operation.
        /// </returns>
        /// <param name="client">The instantiated Http Client <see cref="HttpClient"/></param>
        /// <param name="requestUri">The Uri the request is sent to.</param>
        /// <param name="content">The HTTP request content sent to the server.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="client"/> was null.</exception>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="requestUri"/> was null.</exception>
        public static Task<HttpResponseMessage> PatchAsync(this HttpClient client, string requestUri, HttpContent content, CancellationToken cancellationToken)
        {
            return client.PatchAsync(CreateUri(requestUri), content, cancellationToken);
        }

        /// <summary>
        /// Send a PATCH request with a cancellation token as an asynchronous operation.
        /// </summary>
        /// 
        /// <returns>
        /// Returns <see cref="T:System.Threading.Tasks.Task`1"/>.The task object representing the asynchronous operation.
        /// </returns>
        /// <param name="client">The instantiated Http Client <see cref="HttpClient"/></param>
        /// <param name="requestUri">The Uri the request is sent to.</param>
        /// <param name="content">The HTTP request content sent to the server.</param>
        /// <param name="cancellationToken">A cancellation token that can be used by other objects or threads to receive notice of cancellation.</param>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="client"/> was null.</exception>
        /// <exception cref="T:System.ArgumentNullException">The <paramref name="requestUri"/> was null.</exception>
        public static Task<HttpResponseMessage> PatchAsync(this HttpClient client, Uri requestUri, HttpContent content, CancellationToken cancellationToken)
        {
            return client.SendAsync(new HttpRequestMessage(new HttpMethod("PATCH"), requestUri)
            {
                Content = content
            }, cancellationToken);
        }

        private static Uri CreateUri(string uri)
        {
            return string.IsNullOrEmpty(uri) ? null : new Uri(uri, UriKind.RelativeOrAbsolute);
        }
    }

这样,您就不会在某个静态扩展类中等待和阻止执行,而是像真正在做一个PostAsyncPutAsync调用一样来处理它。您还可以使用相同的重载,并让它HttpClient处理它打算处理的所有内容。


3
这看起来很棒。您应该考虑在.NET Framework的官方存储库中的Github上创建一个Pull-Request,因为它们很受欢迎:github.com/dotnet/corefx/blob/master/src/System.Net.Http/src/…
Alexander Pacha

编辑:有人击败了我,它已经添加到您与其他人链接的回购中。
SSX-SL33PY

5

为了使其正常工作,您需要传递如下内容:

HttpContent httpContent = new StringContent("Your JSON-String", Encoding.UTF8, "application/json-patch+json");
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.