PATCH Async запити з класом Windows.Web.Http.HttpClient


76

Мені потрібно зробити PATCHзапит з Windows.Web.Http.HttpClientкласом, і немає офіційної документації про те, як це зробити. Як я можу це зробити?

Відповіді:


85

Я знайшов, як зробити "спеціальний" 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 відповідь = новий HttpResponseMessage (); `` використання '' `var відповідь = за замовчуванням (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");для String-Contents.
Олександр Пача

Виправте мене, якщо я помиляюся, але метод PATCH означає, що ви змінюєте лише певні дані в JSON. Як ви змінюєте, скажімо, лише назву продукту? Якщо під "Ваш JSON-String" ви маєте на увазі цілий JSON, то я заплутався. Я спробував додати одну властивість, наприклад, HttpContent content = new StringContent("{\"name\":\"John Doe\"", Encoding.UTF8, "application/json");але вміст не додано до запиту.
Калойський

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);
        }
    }

Таким чином , ви не очікували і тримайте виконання в деякому статичному класі розширення, але впоратися з цим , як ніби ви дійсно робите PostAsyncабо на PutAsyncвиклик. У вашому розпорядженні також однакові перевантаження, і ви дозволяєте HttpClientобробляти все, з чим було розроблено.


3
Це виглядає чудово. Вам слід подумати про створення Pull-Request з ним на Github в офіційному сховищі .NET Framework, оскільки вони вітають внески: github.com/dotnet/corefx/blob/master/src/System.Net.Http/src/…
Олександр Пача

Редагувати: Хтось мене побив, це додано до репо, до якого ви зв’язали когось іншого.
SSX-SL33PY

6

Щоб це працювало, потрібно передавати вміст так:

HttpContent httpContent = new StringContent("Your JSON-String", Encoding.UTF8, "application/json-patch+json");
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.