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")
|
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))
|
if (typeof(T) == typeof(IgnoreResponse))
|
||||||
{
|
{
|
||||||
return default;
|
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