Added ValueTask support to API Explorer response types. (#13739)
(cherry picked from commit 24b051de5ee386521f8b286c7c7d4f69ac1f2244) Fixes https://github.com/aspnet/AspNetCore/issues/4883
This commit is contained in:
parent
f9c15caa7a
commit
f1f615282d
|
|
@ -214,7 +214,8 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer
|
|||
{
|
||||
var declaredReturnType = action.MethodInfo.ReturnType;
|
||||
if (declaredReturnType == typeof(void) ||
|
||||
declaredReturnType == typeof(Task))
|
||||
declaredReturnType == typeof(Task) ||
|
||||
declaredReturnType == typeof(ValueTask))
|
||||
{
|
||||
return typeof(void);
|
||||
}
|
||||
|
|
@ -222,7 +223,7 @@ namespace Microsoft.AspNetCore.Mvc.ApiExplorer
|
|||
// Unwrap the type if it's a Task<T>. The Task (non-generic) case was already handled.
|
||||
var unwrappedType = declaredReturnType;
|
||||
if (declaredReturnType.IsGenericType &&
|
||||
declaredReturnType.GetGenericTypeDefinition() == typeof(Task<>))
|
||||
(declaredReturnType.GetGenericTypeDefinition() == typeof(Task<>) || declaredReturnType.GetGenericTypeDefinition() == typeof(ValueTask<>)))
|
||||
{
|
||||
unwrappedType = declaredReturnType.GetGenericArguments()[0];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -472,6 +472,22 @@ namespace Microsoft.AspNetCore.Mvc.Description
|
|||
Assert.NotNull(responseType.ModelMetadata);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetApiDescription_PopulatesResponseType_WithValueTaskOfProduct()
|
||||
{
|
||||
// Arrange
|
||||
var action = CreateActionDescriptor(nameof(ReturnsValueTaskOfProduct));
|
||||
|
||||
// Act
|
||||
var descriptions = GetApiDescriptions(action);
|
||||
|
||||
// Assert
|
||||
var description = Assert.Single(descriptions);
|
||||
var responseType = Assert.Single(description.SupportedResponseTypes);
|
||||
Assert.Equal(typeof(Product), responseType.Type);
|
||||
Assert.NotNull(responseType.ModelMetadata);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(nameof(ReturnsObject))]
|
||||
[InlineData(nameof(ReturnsActionResult))]
|
||||
|
|
@ -479,6 +495,9 @@ namespace Microsoft.AspNetCore.Mvc.Description
|
|||
[InlineData(nameof(ReturnsTaskOfObject))]
|
||||
[InlineData(nameof(ReturnsTaskOfActionResult))]
|
||||
[InlineData(nameof(ReturnsTaskOfJsonResult))]
|
||||
[InlineData(nameof(ReturnsValueTaskOfObject))]
|
||||
[InlineData(nameof(ReturnsValueTaskOfActionResult))]
|
||||
[InlineData(nameof(ReturnsValueTaskOfJsonResult))]
|
||||
public void GetApiDescription_DoesNotPopulatesResponseInformation_WhenUnknown(string methodName)
|
||||
{
|
||||
// Arrange
|
||||
|
|
@ -521,7 +540,7 @@ namespace Microsoft.AspNetCore.Mvc.Description
|
|||
},
|
||||
{
|
||||
typeof(DefaultApiDescriptionProviderTest),
|
||||
nameof(DefaultApiDescriptionProviderTest.ReturnsActionResult),
|
||||
nameof(DefaultApiDescriptionProviderTest.ReturnsValueTaskOfActionResult),
|
||||
filterDescriptors
|
||||
},
|
||||
{
|
||||
|
|
@ -624,6 +643,11 @@ namespace Microsoft.AspNetCore.Mvc.Description
|
|||
nameof(DefaultApiDescriptionProviderTest.ReturnsTask),
|
||||
filterDescriptors
|
||||
},
|
||||
{
|
||||
typeof(DefaultApiDescriptionProviderTest),
|
||||
nameof(DefaultApiDescriptionProviderTest.ReturnsValueTask),
|
||||
filterDescriptors
|
||||
},
|
||||
{
|
||||
typeof(DerivedProducesController),
|
||||
nameof(DerivedProducesController.ReturnsVoid),
|
||||
|
|
@ -634,6 +658,11 @@ namespace Microsoft.AspNetCore.Mvc.Description
|
|||
nameof(DerivedProducesController.ReturnsTask),
|
||||
filterDescriptors
|
||||
},
|
||||
{
|
||||
typeof(DerivedProducesController),
|
||||
nameof(DerivedProducesController.ReturnsValueTask),
|
||||
filterDescriptors
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -895,6 +924,7 @@ namespace Microsoft.AspNetCore.Mvc.Description
|
|||
[Theory]
|
||||
[InlineData(nameof(ReturnsVoid))]
|
||||
[InlineData(nameof(ReturnsTask))]
|
||||
[InlineData(nameof(ReturnsValueTask))]
|
||||
public void GetApiDescription_DefaultVoidStatus(string methodName)
|
||||
{
|
||||
// Arrange
|
||||
|
|
@ -914,6 +944,7 @@ namespace Microsoft.AspNetCore.Mvc.Description
|
|||
[Theory]
|
||||
[InlineData(nameof(ReturnsVoid))]
|
||||
[InlineData(nameof(ReturnsTask))]
|
||||
[InlineData(nameof(ReturnsValueTask))]
|
||||
public void GetApiDescription_VoidWithResponseTypeAttributeStatus(string methodName)
|
||||
{
|
||||
// Arrange
|
||||
|
|
@ -944,6 +975,10 @@ namespace Microsoft.AspNetCore.Mvc.Description
|
|||
[InlineData(nameof(ReturnsTask))]
|
||||
[InlineData(nameof(ReturnsTaskOfActionResult))]
|
||||
[InlineData(nameof(ReturnsTaskOfJsonResult))]
|
||||
[InlineData(nameof(ReturnsValueTask))]
|
||||
[InlineData(nameof(ReturnsValueTaskOfObject))]
|
||||
[InlineData(nameof(ReturnsValueTaskOfActionResult))]
|
||||
[InlineData(nameof(ReturnsValueTaskOfJsonResult))]
|
||||
public void GetApiDescription_PopulatesResponseInformation_WhenSetByFilter(string methodName)
|
||||
{
|
||||
// Arrange
|
||||
|
|
@ -2026,6 +2061,31 @@ namespace Microsoft.AspNetCore.Mvc.Description
|
|||
return null;
|
||||
}
|
||||
|
||||
private ValueTask<Product> ReturnsValueTaskOfProduct()
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
private ValueTask<object> ReturnsValueTaskOfObject()
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
private ValueTask ReturnsValueTask()
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
private ValueTask<IActionResult> ReturnsValueTaskOfActionResult()
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
private ValueTask<JsonResult> ReturnsValueTaskOfJsonResult()
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
private Product ReturnsProduct()
|
||||
{
|
||||
return null;
|
||||
|
|
@ -2196,6 +2256,11 @@ namespace Microsoft.AspNetCore.Mvc.Description
|
|||
return null;
|
||||
}
|
||||
|
||||
public ValueTask ReturnsValueTask()
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
public void ReturnsVoid()
|
||||
{
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue