예제 #1
0
    /// <summary>
    /// Sends an HTTP request and gets the result serialized by JSON.
    /// </summary>
    /// <param name="request">The HTTP request message.</param>
    /// <param name="callback">An optional callback raised on data received.</param>
    /// <param name="cancellationToken">The optional cancellation token.</param>
    /// <returns>A result serialized.</returns>
    /// <exception cref="ArgumentNullException">The request was null.</exception>
    /// <exception cref="FailedHttpException">HTTP response contains failure status code.</exception>
    /// <exception cref="HttpRequestException">The request failed due to an underlying issue such as network connectivity, DNS failure, server certificate validation or timeout.</exception>
    /// <exception cref="InvalidOperationException">The task is cancelled.</exception>
    /// <exception cref="ObjectDisposedException">The inner HTTP web client instance has been disposed.</exception>
    public async Task <T> SendAsync(HttpRequestMessage request, Action <ReceivedEventArgs <T> > callback, CancellationToken cancellationToken = default)
    {
        if (request == null)
        {
            throw new ArgumentNullException(nameof(request), "request should not be null.");
        }
        if (Client == null && !IsNewHttpClientByDefault)
        {
            Client = new HttpClient();
        }
        var client  = Client ?? new HttpClient();
        var timeout = Timeout;

        if (timeout.HasValue)
        {
            try
            {
                client.Timeout = timeout.Value;
            }
            catch (ArgumentException)
            {
            }
        }

        var maxBufferSize = MaxResponseContentBufferSize;

        if (maxBufferSize.HasValue)
        {
            try
            {
                client.MaxResponseContentBufferSize = maxBufferSize.Value;
            }
            catch (ArgumentException)
            {
            }
        }

        Sending?.Invoke(this, new SendingEventArgs(request));
        cancellationToken.ThrowIfCancellationRequested();
        OnSend(request);
        HttpResponseMessage resp = null;
        T valueResult;

        try
        {
            var result = await Tasks.RetryExtensions.ProcessAsync(RetryPolicy, async (CancellationToken cancellation) =>
            {
                resp = await client.SendAsync(request, cancellationToken);
                if (!SerializeEvenIfFailed && !resp.IsSuccessStatusCode)
                {
                    throw FailedHttpException.Create(resp, "Failed to send JSON HTTP web request because of unsuccess status code.");
                }
                var obj = Deserializer != null
#if NET5_0_OR_GREATER
                    ? await HttpClientExtensions.DeserializeAsync(resp.Content, Deserializer, cancellationToken)
#else
                    ? await HttpClientExtensions.DeserializeAsync(resp.Content, Deserializer)
#endif
                    : await HttpClientExtensions.DeserializeJsonAsync <T>(resp.Content, cancellationToken);
                return(obj);
            }, GetExceptionInternal, cancellationToken);

            valueResult = result.Result;
        }
        catch (HttpRequestException)
        {
            OnReceive(default, resp);