【问题标题】:PATCH Async requests with Windows.Web.Http.HttpClient class使用 Windows.Web.Http.HttpClient 类 PATCH 异步请求
【发布时间】:2014-11-30 20:41:44
【问题描述】:

我需要使用Windows.Web.Http.HttpClient 类执行PATCH 请求,并且没有关于如何执行此操作的官方文档。我该怎么做?

【问题讨论】:

    标签: c# http patch dotnet-httpclient


    【解决方案1】:

    我找到了如何使用之前的 System.Net.Http.HttpClienthere 来执行“自定义”PATCH 请求,然后一直在摆弄直到我让它在 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(); ``` 使用 ``` var response = default(HttpResponseMessage); ```
    【解决方案2】:

    更新:请参阅下面的SSX-SL33PY's answer 以获得更好的解决方案,它的作用相同。

    您可以编写与扩展方法完全相同的方法,因此您可以直接在 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);
    

    【讨论】:

    • 如何传递内容?
    • 你看到第二个参数了吗?尝试这样的事情:HttpContent httpContent = new StringContent("Your JSON-String", Encoding.UTF8, "application/json"); for String-Contents。
    • 如果我错了,请纠正我,但 PATCH 方法意味着您只修改 JSON 中的特定数据。你如何修改,比方说,只是一个产品的名称?如果“你的 JSON 字符串”是指整个 JSON,那么我很困惑。我尝试添加像 HttpContent content = new StringContent("{\"name\":\"John Doe\"", Encoding.UTF8, "application/json"); 这样的单个属性,但内容未添加到请求中。
    【解决方案3】:

    我想扩展@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 处理它设计处理的所有内容。

    【讨论】:

    【解决方案4】:

    要让它工作,你需要像这样传递内容:

    HttpContent httpContent = new StringContent("Your JSON-String", Encoding.UTF8, "application/json-patch+json");
    

    【讨论】:

      【解决方案5】:

      第 1 步:创建一个静态类(我已创建为扩展)

      public static class Extention
      {
          public static Task<HttpResponseMessage> PatchAsJsonAsync<T>(this HttpClient 
          client, string requestUri, T value)
          {
              var content = new ObjectContent<T>(value, new JsonMediaTypeFormatter());
              var request = new HttpRequestMessage(new HttpMethod("PATCH"), requestUri) 
              { Content = content };
      
              return client.SendAsync(request);
          }
      }
      

      第 2 步:在您的 api 请求中调用此方法

      private static HttpClient client = new HttpClient();
      var response = Extention.PatchAsJsonAsync<UserUpdateAPIModel>(client, "https://api.go1.com/v2/users/5886043", data);
      

      问题解决了,这里如果是普通的url,你可以自己练习一下

      【讨论】:

        猜你喜欢
        • 2018-04-24
        • 2019-07-21
        • 1970-01-01
        • 2016-08-19
        • 2020-05-03
        • 1970-01-01
        • 2017-01-23
        • 1970-01-01
        • 2015-06-09
        相关资源
        最近更新 更多