使用 Windows.Web.Http.HttpClient 类 PATCH 异步请求
Posted
技术标签:
【中文标题】使用 Windows.Web.Http.HttpClient 类 PATCH 异步请求【英文标题】:PATCH Async requests with Windows.Web.Http.HttpClient class 【发布时间】:2014-11-30 20:41:44 【问题描述】:我需要使用Windows.Web.Http.HttpClient
类执行PATCH
请求,并且没有关于如何执行此操作的官方文档。我该怎么做?
【问题讨论】:
【参考方案1】:我找到了如何使用之前的 System.Net.Http.HttpClient
类 here 来执行“自定义”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);
通过这种方式,您不会在某个静态扩展类中等待和暂停执行,但您可以像处理 PostAsync
或 PutAsync
调用一样处理它。您还可以使用相同的重载,并让 HttpClient
处理它设计处理的所有内容。
【讨论】:
这看起来很棒。您应该考虑在 .NET Framework 的官方存储库中的 Github 上创建一个 Pull-Request,因为他们欢迎贡献:github.com/dotnet/corefx/blob/master/src/System.Net.Http/src/… 编辑:有人打败了我,它已被添加到您由其他人链接的存储库中。【参考方案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,你可以自己练习一下
【讨论】:
以上是关于使用 Windows.Web.Http.HttpClient 类 PATCH 异步请求的主要内容,如果未能解决你的问题,请参考以下文章
在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?
Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)