private static async Task ThrowIfApiFailAsync(HttpResponseMessage response) { if (response.IsSuccessStatusCode) { return; } var errorDetails = await GetErrorResponseAsync(response); throw new ApiCallFailedException(new ApiResponse(response.StatusCode, ApiRateLimitDetails.CreateFromResponse(response), errorDetails)); }
/// <summary> /// Sends the HTTP request to the server /// </summary> /// <typeparam name="TResponse"></typeparam> /// <param name="relativeUrl"> /// The URL to the endpoint, relative to the base nation URL /// (https://{nationSlug}.nationbuilder.com) /// </param> /// <param name="method">The HTTP method (verb) to use for the request</param> /// <param name="content">The content for the body of the request</param> /// <param name="cancellationToken">Token allowing request to be cancelled</param> /// <param name="isContentAlreadyJson">Whether or not the content has already been serialized to JSON</param> /// <param name="throwOnFailureCodes">Whether to throw an exception if a failure response is returned from the server</param> /// <param name="isNoResponse">Whether we can ignore the response body</param> /// /// <param name="includeCredentials">Whether to include credentials in the request. Defaults to true.</param> /// <returns>Details about the response from the API</returns> private async Task <ApiResponse <TResponse> > SendJsonAsync <TResponse>(string relativeUrl, HttpMethod method, object content, CancellationToken cancellationToken, bool isContentAlreadyJson, bool throwOnFailureCodes, bool isNoResponse = false, bool includeCredentials = true) where TResponse : class { var endpoint = includeCredentials ? AddCredentialsToUrl(relativeUrl) : relativeUrl; endpoint = GetFullEndpointUrl(Options, endpoint); var useFakeDelete = method == HttpMethod.Delete && content != null; var request = new HttpRequestMessage { Content = GetJsonContent(content, isContentAlreadyJson), Method = useFakeDelete ? HttpMethod.Post : method, RequestUri = new Uri(endpoint) }; if (useFakeDelete) { request.Headers.Add("X-HTTP-Method-Override", "DELETE"); } var response = await Client.SendAsync(request, cancellationToken); var rateLimit = ApiRateLimitDetails.CreateFromResponse(response); if (!response.IsSuccessStatusCode && !throwOnFailureCodes) { return(new ApiResponse <TResponse>(response.StatusCode, rateLimit, null, await GetErrorResponseAsync(response))); } await ThrowIfApiFailAsync(response); // If we can ignore the response, just return without it if (isNoResponse) { return(new ApiResponse <TResponse>(response.StatusCode, rateLimit, null)); } var resultJson = await response.Content.ReadAsStringAsync(); var resultObject = JsonConvert.DeserializeObject <TResponse>(resultJson); return(new ApiResponse <TResponse>(response.StatusCode, rateLimit, resultObject)); }