HttpClientJsonExtensions better handling for failed requests (imported from Blazor PR 1660) (#4788)
This commit is contained in:
parent
93127b39e8
commit
8a9df6c873
|
|
@ -101,6 +101,10 @@ namespace Microsoft.AspNetCore.Components
|
|||
Content = new StringContent(requestJson, Encoding.UTF8, "application/json")
|
||||
});
|
||||
|
||||
// Make sure the call was successful before we
|
||||
// attempt to process the response content
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
if (typeof(T) == typeof(IgnoreResponse))
|
||||
{
|
||||
return default;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,159 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.JSInterop;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Components.Test
|
||||
{
|
||||
public class HttpClientJsonExtensionsTest
|
||||
{
|
||||
const string TestUri = "http://example.com/some/uri";
|
||||
|
||||
[Fact]
|
||||
public async Task GetJson_Success()
|
||||
{
|
||||
// Arrange
|
||||
var httpClient = new HttpClient(new TestHttpMessageHandler(req =>
|
||||
{
|
||||
Assert.Equal(TestUri, req.RequestUri.AbsoluteUri);
|
||||
return Task.FromResult(CreateJsonResponse(HttpStatusCode.OK, new Person
|
||||
{
|
||||
Name = "Abc",
|
||||
Age = 123
|
||||
}));
|
||||
}));
|
||||
|
||||
// Act
|
||||
var result = await httpClient.GetJsonAsync<Person>(TestUri);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("Abc", result.Name);
|
||||
Assert.Equal(123, result.Age);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetJson_Failure()
|
||||
{
|
||||
// Arrange
|
||||
var httpClient = new HttpClient(new TestHttpMessageHandler(req =>
|
||||
{
|
||||
Assert.Equal(TestUri, req.RequestUri.AbsoluteUri);
|
||||
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.NotFound));
|
||||
}));
|
||||
|
||||
// Act/Assert
|
||||
var ex = await Assert.ThrowsAsync<HttpRequestException>(
|
||||
() => httpClient.GetJsonAsync<Person>(TestUri));
|
||||
Assert.Contains("404 (Not Found)", ex.Message);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Put")]
|
||||
[InlineData("Post")]
|
||||
[InlineData("Patch")]
|
||||
[InlineData("Delete")]
|
||||
[InlineData("MyArtificialMethod")]
|
||||
public async Task SendJson_Success(string httpMethodString)
|
||||
{
|
||||
var httpMethod = new HttpMethod(httpMethodString);
|
||||
var requestContent = new { MyProp = true, OtherProp = "Hello" };
|
||||
|
||||
// Arrange
|
||||
var httpClient = new HttpClient(new TestHttpMessageHandler(async req =>
|
||||
{
|
||||
Assert.Equal(httpMethod, req.Method);
|
||||
Assert.Equal(TestUri, req.RequestUri.AbsoluteUri);
|
||||
Assert.Equal(Json.Serialize(requestContent), await ((StringContent)req.Content).ReadAsStringAsync());
|
||||
return CreateJsonResponse(HttpStatusCode.OK, new Person
|
||||
{
|
||||
Name = "Abc",
|
||||
Age = 123
|
||||
});
|
||||
}));
|
||||
|
||||
// Act
|
||||
var result = await Send(httpClient, httpMethodString, requestContent);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("Abc", result.Name);
|
||||
Assert.Equal(123, result.Age);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("Put")]
|
||||
[InlineData("Post")]
|
||||
[InlineData("Patch")]
|
||||
[InlineData("Delete")]
|
||||
[InlineData("MyArtificialMethod")]
|
||||
public async Task SendJson_Failure(string httpMethodString)
|
||||
{
|
||||
var httpMethod = new HttpMethod(httpMethodString);
|
||||
var requestContent = new { MyProp = true, OtherProp = "Hello" };
|
||||
|
||||
// Arrange
|
||||
var httpClient = new HttpClient(new TestHttpMessageHandler(async req =>
|
||||
{
|
||||
Assert.Equal(httpMethod, req.Method);
|
||||
Assert.Equal(TestUri, req.RequestUri.AbsoluteUri);
|
||||
Assert.Equal(Json.Serialize(requestContent), await ((StringContent)req.Content).ReadAsStringAsync());
|
||||
return new HttpResponseMessage(HttpStatusCode.BadGateway);
|
||||
}));
|
||||
|
||||
// Act/Assert
|
||||
var ex = await Assert.ThrowsAsync<HttpRequestException>(
|
||||
() => Send(httpClient, httpMethodString, requestContent));
|
||||
Assert.Contains("502 (Bad Gateway)", ex.Message);
|
||||
}
|
||||
|
||||
HttpResponseMessage CreateJsonResponse(HttpStatusCode statusCode, object content)
|
||||
{
|
||||
return new HttpResponseMessage(statusCode)
|
||||
{
|
||||
Content = new StringContent(Json.Serialize(content))
|
||||
};
|
||||
}
|
||||
|
||||
Task<Person> Send(HttpClient httpClient, string httpMethodString, object requestContent)
|
||||
{
|
||||
// For methods with convenience overloads, show those overloads work
|
||||
switch (httpMethodString)
|
||||
{
|
||||
case "post":
|
||||
return httpClient.PostJsonAsync<Person>(TestUri, requestContent);
|
||||
case "put":
|
||||
return httpClient.PutJsonAsync<Person>(TestUri, requestContent);
|
||||
default:
|
||||
return httpClient.SendJsonAsync<Person>(new HttpMethod(httpMethodString), TestUri, requestContent);
|
||||
}
|
||||
}
|
||||
|
||||
class Person
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Age { get; set; }
|
||||
}
|
||||
|
||||
class TestHttpMessageHandler : HttpMessageHandler
|
||||
{
|
||||
private readonly Func<HttpRequestMessage, Task<HttpResponseMessage>> _sendDelegate;
|
||||
|
||||
public TestHttpMessageHandler(Func<HttpRequestMessage, Task<HttpResponseMessage>> sendDelegate)
|
||||
{
|
||||
_sendDelegate = sendDelegate;
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
=> base.Dispose(disposing);
|
||||
|
||||
protected override Task<HttpResponseMessage> SendAsync(
|
||||
HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
=> _sendDelegate(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue