Skip to content

Commit 1fc1e83

Browse files
committed
Update ApiExplorer logic to never infer Task or ValueTask as the responseType
1 parent 8a8eec8 commit 1fc1e83

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

src/Mvc/Mvc.ApiExplorer/src/EndpointMetadataApiDescriptionProvider.cs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -332,10 +332,9 @@ private static void AddSupportedResponseTypes(
332332
var defaultErrorType = errorMetadata?.Type ?? typeof(void);
333333
var contentTypes = new MediaTypeCollection();
334334

335-
// If the return type is an IResult or an awaitable IResult, then we should treat it as a void return type
336-
// since we can't infer anything without additional metadata.
337-
if (typeof(IResult).IsAssignableFrom(responseType) ||
338-
producesResponseMetadata.Any(metadata => typeof(IResult).IsAssignableFrom(metadata.Type)))
335+
// If the return type is an IResult or wrapped in a Task or ValueTask, then we should treat it as a void return type
336+
// since we can't infer anything without additional metadata or requiring unreferenced code.
337+
if (IsTaskOrValueTask(responseType) || typeof(IResult).IsAssignableFrom(responseType))
339338
{
340339
responseType = typeof(void);
341340
}
@@ -427,6 +426,23 @@ static bool TypesAreCompatible(Type? apiResponseType, Type? metadataType)
427426
return apiResponseType == metadataType ||
428427
metadataType?.IsAssignableFrom(apiResponseType) == true;
429428
}
429+
430+
static bool IsTaskOrValueTask(Type returnType)
431+
{
432+
// If this method did not need to be trim-safe, we would use CoercedAwaitableInfo.IsTypeAwaitable, but we cannot.
433+
if (returnType.IsAssignableFrom(typeof(Task)) || returnType.IsAssignableFrom(typeof(ValueTask)))
434+
{
435+
return true;
436+
}
437+
438+
if (returnType.FullName is null)
439+
{
440+
return false;
441+
}
442+
443+
return returnType.FullName.StartsWith("System.Threading.Tasks.Task`1[", StringComparison.Ordinal) ||
444+
returnType.FullName.StartsWith("System.Threading.Tasks.ValueTask`1[", StringComparison.Ordinal);
445+
}
430446
}
431447

432448
private static ApiResponseType CreateDefaultApiResponseType(Type responseType)

0 commit comments

Comments
 (0)