diff --git a/src/Http/Http.Extensions/gen/RequestDelegateGenerator.cs b/src/Http/Http.Extensions/gen/RequestDelegateGenerator.cs index 59890ed0b764..13d303d40c3b 100644 --- a/src/Http/Http.Extensions/gen/RequestDelegateGenerator.cs +++ b/src/Http/Http.Extensions/gen/RequestDelegateGenerator.cs @@ -80,6 +80,7 @@ public void Initialize(IncrementalGeneratorInitializationContext context) codeWriter.WriteLine($"var handler = ({endpoint.EmitHandlerDelegateCast()})del;"); codeWriter.WriteLine("EndpointFilterDelegate? filteredInvocation = null;"); endpoint.EmitRouteOrQueryResolver(codeWriter); + endpoint.EmitJsonPreparation(codeWriter); codeWriter.WriteLineNoTabs(string.Empty); codeWriter.WriteLine("if (options?.EndpointBuilder?.FilterFactories.Count > 0)"); codeWriter.StartBlock(); diff --git a/src/Http/Http.Extensions/gen/RequestDelegateGeneratorSources.cs b/src/Http/Http.Extensions/gen/RequestDelegateGeneratorSources.cs index 213bc51fd03d..9affd8a989e6 100644 --- a/src/Http/Http.Extensions/gen/RequestDelegateGeneratorSources.cs +++ b/src/Http/Http.Extensions/gen/RequestDelegateGeneratorSources.cs @@ -47,19 +47,24 @@ namespace Microsoft.AspNetCore.Http.Generated using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; + using System.Text.Json; + using System.Text.Json.Serialization.Metadata; using System.Threading.Tasks; using System.IO; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Http.Json; using Microsoft.AspNetCore.Http.Metadata; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Primitives; + using Microsoft.Extensions.Options; using MetadataPopulator = System.Func; using RequestDelegateFactoryFunc = System.Func; @@ -109,6 +114,17 @@ private static Func ResolveFromRouteOrQuery(string pa : (httpContext) => httpContext.Request.Query[parameterName]; } + private static Task WriteToResponseAsync(T? value, HttpContext httpContext, JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options) + { + var runtimeType = value?.GetType(); + if (runtimeType is null || jsonTypeInfo.Type == runtimeType || jsonTypeInfo.PolymorphismOptions is not null) + { + return httpContext.Response.WriteAsJsonAsync(value!, jsonTypeInfo); + } + + return httpContext.Response.WriteAsJsonAsync(value!, options.GetTypeInfo(runtimeType)); + } + private static async ValueTask<(bool, T?)> TryResolveBody(HttpContext httpContext, bool allowEmpty) { var feature = httpContext.Features.Get(); diff --git a/src/Http/Http.Extensions/gen/StaticRouteHandlerModel/Emitters/EndpointJsonResponseEmitter.cs b/src/Http/Http.Extensions/gen/StaticRouteHandlerModel/Emitters/EndpointJsonResponseEmitter.cs new file mode 100644 index 000000000000..93be63a9e882 --- /dev/null +++ b/src/Http/Http.Extensions/gen/StaticRouteHandlerModel/Emitters/EndpointJsonResponseEmitter.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Text; + +namespace Microsoft.AspNetCore.Http.Generators.StaticRouteHandlerModel.Emitters; + +internal static class EndpointJsonResponseEmitter +{ + internal static void EmitJsonPreparation(this Endpoint endpoint, CodeWriter codeWriter) + { + if (endpoint.Response.IsSerializable) + { + var typeName = endpoint.Response.ResponseType.ToDisplayString(EmitterConstants.DisplayFormat); + + codeWriter.WriteLine("var serviceProvider = options?.ServiceProvider ?? options?.EndpointBuilder?.ApplicationServices;"); + codeWriter.WriteLine("var serializerOptions = serviceProvider?.GetService>()?.Value.SerializerOptions ?? new JsonOptions().SerializerOptions;"); + codeWriter.WriteLine($"var jsonTypeInfo = (JsonTypeInfo<{typeName}>)serializerOptions.GetTypeInfo(typeof({typeName}));"); + } + } + + internal static string EmitJsonResponse(this Endpoint endpoint) + { + if (endpoint.Response.ResponseType.IsSealed || endpoint.Response.ResponseType.IsValueType) + { + return $"httpContext.Response.WriteAsJsonAsync(result, jsonTypeInfo);"; + } + else + { + return $"GeneratedRouteBuilderExtensionsCore.WriteToResponseAsync(result, httpContext, jsonTypeInfo, serializerOptions);"; + } + } +} diff --git a/src/Http/Http.Extensions/gen/StaticRouteHandlerModel/EndpointResponse.cs b/src/Http/Http.Extensions/gen/StaticRouteHandlerModel/EndpointResponse.cs index d2cbf2536245..1c18b3de6294 100644 --- a/src/Http/Http.Extensions/gen/StaticRouteHandlerModel/EndpointResponse.cs +++ b/src/Http/Http.Extensions/gen/StaticRouteHandlerModel/EndpointResponse.cs @@ -19,6 +19,7 @@ internal class EndpointResponse public bool IsAwaitable { get; set; } public bool IsVoid { get; set; } public bool IsIResult { get; set; } + public bool IsSerializable { get; set; } private WellKnownTypes WellKnownTypes { get; init; } @@ -30,6 +31,7 @@ internal EndpointResponse(IMethodSymbol method, WellKnownTypes wellKnownTypes) IsAwaitable = GetIsAwaitable(method); IsVoid = method.ReturnsVoid; IsIResult = GetIsIResult(); + IsSerializable = !IsIResult && !IsVoid && ResponseType.SpecialType != SpecialType.System_String && ResponseType.SpecialType != SpecialType.System_Object; ContentType = GetContentType(method); } diff --git a/src/Http/Http.Extensions/gen/StaticRouteHandlerModel/StaticRouteHandlerModel.Emitter.cs b/src/Http/Http.Extensions/gen/StaticRouteHandlerModel/StaticRouteHandlerModel.Emitter.cs index 64e33ef93f07..301ce58c6251 100644 --- a/src/Http/Http.Extensions/gen/StaticRouteHandlerModel/StaticRouteHandlerModel.Emitter.cs +++ b/src/Http/Http.Extensions/gen/StaticRouteHandlerModel/StaticRouteHandlerModel.Emitter.cs @@ -132,7 +132,7 @@ private static string EmitResponseWritingCall(this Endpoint endpoint) } else if (!endpoint.Response.IsVoid) { - return $"{returnOrAwait} httpContext.Response.WriteAsJsonAsync(result);"; + return $"{returnOrAwait} {endpoint.EmitJsonResponse()}"; } else if (!endpoint.Response.IsAwaitable && endpoint.Response.IsVoid) { diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitBodyParam_ComplexReturn_Snapshot.generated.txt b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitBodyParam_ComplexReturn_Snapshot.generated.txt index ca611ebf62cd..6ea1d07f7d37 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitBodyParam_ComplexReturn_Snapshot.generated.txt +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitBodyParam_ComplexReturn_Snapshot.generated.txt @@ -63,19 +63,24 @@ namespace Microsoft.AspNetCore.Http.Generated using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; + using System.Text.Json; + using System.Text.Json.Serialization.Metadata; using System.Threading.Tasks; using System.IO; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Http.Json; using Microsoft.AspNetCore.Http.Metadata; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Primitives; + using Microsoft.Extensions.Options; using MetadataPopulator = System.Func; using RequestDelegateFactoryFunc = System.Func; @@ -276,6 +281,17 @@ namespace Microsoft.AspNetCore.Http.Generated : (httpContext) => httpContext.Request.Query[parameterName]; } + private static Task WriteToResponseAsync(T? value, HttpContext httpContext, JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options) + { + var runtimeType = value?.GetType(); + if (runtimeType is null || jsonTypeInfo.Type == runtimeType || jsonTypeInfo.PolymorphismOptions is not null) + { + return httpContext.Response.WriteAsJsonAsync(value!, jsonTypeInfo); + } + + return httpContext.Response.WriteAsJsonAsync(value!, options.GetTypeInfo(runtimeType)); + } + private static async ValueTask<(bool, T?)> TryResolveBody(HttpContext httpContext, bool allowEmpty) { var feature = httpContext.Features.Get(); diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitServiceParam_SimpleReturn_Snapshot.generated.txt b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitServiceParam_SimpleReturn_Snapshot.generated.txt index 567b932368bc..c2f4dbe46026 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitServiceParam_SimpleReturn_Snapshot.generated.txt +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitServiceParam_SimpleReturn_Snapshot.generated.txt @@ -93,19 +93,24 @@ namespace Microsoft.AspNetCore.Http.Generated using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; + using System.Text.Json; + using System.Text.Json.Serialization.Metadata; using System.Threading.Tasks; using System.IO; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Http.Json; using Microsoft.AspNetCore.Http.Metadata; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Primitives; + using Microsoft.Extensions.Options; using MetadataPopulator = System.Func; using RequestDelegateFactoryFunc = System.Func; @@ -354,6 +359,17 @@ namespace Microsoft.AspNetCore.Http.Generated : (httpContext) => httpContext.Request.Query[parameterName]; } + private static Task WriteToResponseAsync(T? value, HttpContext httpContext, JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options) + { + var runtimeType = value?.GetType(); + if (runtimeType is null || jsonTypeInfo.Type == runtimeType || jsonTypeInfo.PolymorphismOptions is not null) + { + return httpContext.Response.WriteAsJsonAsync(value!, jsonTypeInfo); + } + + return httpContext.Response.WriteAsJsonAsync(value!, options.GetTypeInfo(runtimeType)); + } + private static async ValueTask<(bool, T?)> TryResolveBody(HttpContext httpContext, bool allowEmpty) { var feature = httpContext.Features.Get(); diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitSource_SimpleReturn_Snapshot.generated.txt b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitSource_SimpleReturn_Snapshot.generated.txt index 7ad0053433d7..07cd0c910541 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitSource_SimpleReturn_Snapshot.generated.txt +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_ExplicitSource_SimpleReturn_Snapshot.generated.txt @@ -63,19 +63,24 @@ namespace Microsoft.AspNetCore.Http.Generated using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; + using System.Text.Json; + using System.Text.Json.Serialization.Metadata; using System.Threading.Tasks; using System.IO; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Http.Json; using Microsoft.AspNetCore.Http.Metadata; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Primitives; + using Microsoft.Extensions.Options; using MetadataPopulator = System.Func; using RequestDelegateFactoryFunc = System.Func; @@ -506,6 +511,17 @@ namespace Microsoft.AspNetCore.Http.Generated : (httpContext) => httpContext.Request.Query[parameterName]; } + private static Task WriteToResponseAsync(T? value, HttpContext httpContext, JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options) + { + var runtimeType = value?.GetType(); + if (runtimeType is null || jsonTypeInfo.Type == runtimeType || jsonTypeInfo.PolymorphismOptions is not null) + { + return httpContext.Response.WriteAsJsonAsync(value!, jsonTypeInfo); + } + + return httpContext.Response.WriteAsJsonAsync(value!, options.GetTypeInfo(runtimeType)); + } + private static async ValueTask<(bool, T?)> TryResolveBody(HttpContext httpContext, bool allowEmpty) { var feature = httpContext.Features.Get(); diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_MultipleSpecialTypeParam_StringReturn.generated.txt b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_MultipleSpecialTypeParam_StringReturn.generated.txt index bee9a30e8fa7..d7d1b6352e9b 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_MultipleSpecialTypeParam_StringReturn.generated.txt +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_MultipleSpecialTypeParam_StringReturn.generated.txt @@ -63,19 +63,24 @@ namespace Microsoft.AspNetCore.Http.Generated using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; + using System.Text.Json; + using System.Text.Json.Serialization.Metadata; using System.Threading.Tasks; using System.IO; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Http.Json; using Microsoft.AspNetCore.Http.Metadata; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Primitives; + using Microsoft.Extensions.Options; using MetadataPopulator = System.Func; using RequestDelegateFactoryFunc = System.Func; @@ -200,6 +205,17 @@ namespace Microsoft.AspNetCore.Http.Generated : (httpContext) => httpContext.Request.Query[parameterName]; } + private static Task WriteToResponseAsync(T? value, HttpContext httpContext, JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options) + { + var runtimeType = value?.GetType(); + if (runtimeType is null || jsonTypeInfo.Type == runtimeType || jsonTypeInfo.PolymorphismOptions is not null) + { + return httpContext.Response.WriteAsJsonAsync(value!, jsonTypeInfo); + } + + return httpContext.Response.WriteAsJsonAsync(value!, options.GetTypeInfo(runtimeType)); + } + private static async ValueTask<(bool, T?)> TryResolveBody(HttpContext httpContext, bool allowEmpty) { var feature = httpContext.Features.Get(); diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_MultipleStringParam_StringReturn.generated.txt b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_MultipleStringParam_StringReturn.generated.txt index d99cb757f377..ff5e719e011a 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_MultipleStringParam_StringReturn.generated.txt +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_MultipleStringParam_StringReturn.generated.txt @@ -63,19 +63,24 @@ namespace Microsoft.AspNetCore.Http.Generated using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; + using System.Text.Json; + using System.Text.Json.Serialization.Metadata; using System.Threading.Tasks; using System.IO; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Http.Json; using Microsoft.AspNetCore.Http.Metadata; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Primitives; + using Microsoft.Extensions.Options; using MetadataPopulator = System.Func; using RequestDelegateFactoryFunc = System.Func; @@ -228,6 +233,17 @@ namespace Microsoft.AspNetCore.Http.Generated : (httpContext) => httpContext.Request.Query[parameterName]; } + private static Task WriteToResponseAsync(T? value, HttpContext httpContext, JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options) + { + var runtimeType = value?.GetType(); + if (runtimeType is null || jsonTypeInfo.Type == runtimeType || jsonTypeInfo.PolymorphismOptions is not null) + { + return httpContext.Response.WriteAsJsonAsync(value!, jsonTypeInfo); + } + + return httpContext.Response.WriteAsJsonAsync(value!, options.GetTypeInfo(runtimeType)); + } + private static async ValueTask<(bool, T?)> TryResolveBody(HttpContext httpContext, bool allowEmpty) { var feature = httpContext.Features.Get(); diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_NoParam_StringReturn_WithFilter.generated.txt b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_NoParam_StringReturn_WithFilter.generated.txt index 59cd72d1d998..741931d0a9cc 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_NoParam_StringReturn_WithFilter.generated.txt +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_NoParam_StringReturn_WithFilter.generated.txt @@ -63,19 +63,24 @@ namespace Microsoft.AspNetCore.Http.Generated using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; + using System.Text.Json; + using System.Text.Json.Serialization.Metadata; using System.Threading.Tasks; using System.IO; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Http.Json; using Microsoft.AspNetCore.Http.Metadata; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Primitives; + using Microsoft.Extensions.Options; using MetadataPopulator = System.Func; using RequestDelegateFactoryFunc = System.Func; @@ -194,6 +199,17 @@ namespace Microsoft.AspNetCore.Http.Generated : (httpContext) => httpContext.Request.Query[parameterName]; } + private static Task WriteToResponseAsync(T? value, HttpContext httpContext, JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options) + { + var runtimeType = value?.GetType(); + if (runtimeType is null || jsonTypeInfo.Type == runtimeType || jsonTypeInfo.PolymorphismOptions is not null) + { + return httpContext.Response.WriteAsJsonAsync(value!, jsonTypeInfo); + } + + return httpContext.Response.WriteAsJsonAsync(value!, options.GetTypeInfo(runtimeType)); + } + private static async ValueTask<(bool, T?)> TryResolveBody(HttpContext httpContext, bool allowEmpty) { var feature = httpContext.Features.Get(); diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_SingleComplexTypeParam_StringReturn.generated.txt b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_SingleComplexTypeParam_StringReturn.generated.txt index 289fa78f73ca..42a2c35fca74 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_SingleComplexTypeParam_StringReturn.generated.txt +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_SingleComplexTypeParam_StringReturn.generated.txt @@ -63,19 +63,24 @@ namespace Microsoft.AspNetCore.Http.Generated using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; + using System.Text.Json; + using System.Text.Json.Serialization.Metadata; using System.Threading.Tasks; using System.IO; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Http.Json; using Microsoft.AspNetCore.Http.Metadata; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Primitives; + using Microsoft.Extensions.Options; using MetadataPopulator = System.Func; using RequestDelegateFactoryFunc = System.Func; @@ -220,6 +225,17 @@ namespace Microsoft.AspNetCore.Http.Generated : (httpContext) => httpContext.Request.Query[parameterName]; } + private static Task WriteToResponseAsync(T? value, HttpContext httpContext, JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options) + { + var runtimeType = value?.GetType(); + if (runtimeType is null || jsonTypeInfo.Type == runtimeType || jsonTypeInfo.PolymorphismOptions is not null) + { + return httpContext.Response.WriteAsJsonAsync(value!, jsonTypeInfo); + } + + return httpContext.Response.WriteAsJsonAsync(value!, options.GetTypeInfo(runtimeType)); + } + private static async ValueTask<(bool, T?)> TryResolveBody(HttpContext httpContext, bool allowEmpty) { var feature = httpContext.Features.Get(); diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_SingleEnumParam_StringReturn.generated.txt b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_SingleEnumParam_StringReturn.generated.txt index 28dd1594d12b..a6c76fec2e58 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_SingleEnumParam_StringReturn.generated.txt +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_SingleEnumParam_StringReturn.generated.txt @@ -63,19 +63,24 @@ namespace Microsoft.AspNetCore.Http.Generated using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; + using System.Text.Json; + using System.Text.Json.Serialization.Metadata; using System.Threading.Tasks; using System.IO; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Http.Json; using Microsoft.AspNetCore.Http.Metadata; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Primitives; + using Microsoft.Extensions.Options; using MetadataPopulator = System.Func; using RequestDelegateFactoryFunc = System.Func; @@ -220,6 +225,17 @@ namespace Microsoft.AspNetCore.Http.Generated : (httpContext) => httpContext.Request.Query[parameterName]; } + private static Task WriteToResponseAsync(T? value, HttpContext httpContext, JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options) + { + var runtimeType = value?.GetType(); + if (runtimeType is null || jsonTypeInfo.Type == runtimeType || jsonTypeInfo.PolymorphismOptions is not null) + { + return httpContext.Response.WriteAsJsonAsync(value!, jsonTypeInfo); + } + + return httpContext.Response.WriteAsJsonAsync(value!, options.GetTypeInfo(runtimeType)); + } + private static async ValueTask<(bool, T?)> TryResolveBody(HttpContext httpContext, bool allowEmpty) { var feature = httpContext.Features.Get(); diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_SingleNullableStringParam_WithEmptyQueryStringValueProvided_StringReturn.generated.txt b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_SingleNullableStringParam_WithEmptyQueryStringValueProvided_StringReturn.generated.txt index 302a18ddbb48..016f1532e825 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_SingleNullableStringParam_WithEmptyQueryStringValueProvided_StringReturn.generated.txt +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_SingleNullableStringParam_WithEmptyQueryStringValueProvided_StringReturn.generated.txt @@ -63,19 +63,24 @@ namespace Microsoft.AspNetCore.Http.Generated using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; + using System.Text.Json; + using System.Text.Json.Serialization.Metadata; using System.Threading.Tasks; using System.IO; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Http.Json; using Microsoft.AspNetCore.Http.Metadata; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Primitives; + using Microsoft.Extensions.Options; using MetadataPopulator = System.Func; using RequestDelegateFactoryFunc = System.Func; @@ -204,6 +209,17 @@ namespace Microsoft.AspNetCore.Http.Generated : (httpContext) => httpContext.Request.Query[parameterName]; } + private static Task WriteToResponseAsync(T? value, HttpContext httpContext, JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options) + { + var runtimeType = value?.GetType(); + if (runtimeType is null || jsonTypeInfo.Type == runtimeType || jsonTypeInfo.PolymorphismOptions is not null) + { + return httpContext.Response.WriteAsJsonAsync(value!, jsonTypeInfo); + } + + return httpContext.Response.WriteAsJsonAsync(value!, options.GetTypeInfo(runtimeType)); + } + private static async ValueTask<(bool, T?)> TryResolveBody(HttpContext httpContext, bool allowEmpty) { var feature = httpContext.Features.Get(); diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_SingleTimeOnlyParam_StringReturn.generated.txt b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_SingleTimeOnlyParam_StringReturn.generated.txt index f490db496c42..67eaf05b1f4f 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_SingleTimeOnlyParam_StringReturn.generated.txt +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/MapAction_SingleTimeOnlyParam_StringReturn.generated.txt @@ -63,19 +63,24 @@ namespace Microsoft.AspNetCore.Http.Generated using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; + using System.Text.Json; + using System.Text.Json.Serialization.Metadata; using System.Threading.Tasks; using System.IO; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Http.Json; using Microsoft.AspNetCore.Http.Metadata; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Primitives; + using Microsoft.Extensions.Options; using MetadataPopulator = System.Func; using RequestDelegateFactoryFunc = System.Func; @@ -220,6 +225,17 @@ namespace Microsoft.AspNetCore.Http.Generated : (httpContext) => httpContext.Request.Query[parameterName]; } + private static Task WriteToResponseAsync(T? value, HttpContext httpContext, JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options) + { + var runtimeType = value?.GetType(); + if (runtimeType is null || jsonTypeInfo.Type == runtimeType || jsonTypeInfo.PolymorphismOptions is not null) + { + return httpContext.Response.WriteAsJsonAsync(value!, jsonTypeInfo); + } + + return httpContext.Response.WriteAsJsonAsync(value!, options.GetTypeInfo(runtimeType)); + } + private static async ValueTask<(bool, T?)> TryResolveBody(HttpContext httpContext, bool allowEmpty) { var feature = httpContext.Features.Get(); diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/Multiple_MapAction_NoParam_StringReturn.generated.txt b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/Multiple_MapAction_NoParam_StringReturn.generated.txt index 4978126343bb..b829bda61594 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/Multiple_MapAction_NoParam_StringReturn.generated.txt +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/Multiple_MapAction_NoParam_StringReturn.generated.txt @@ -93,19 +93,24 @@ namespace Microsoft.AspNetCore.Http.Generated using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; + using System.Text.Json; + using System.Text.Json.Serialization.Metadata; using System.Threading.Tasks; using System.IO; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Http.Json; using Microsoft.AspNetCore.Http.Metadata; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Primitives; + using Microsoft.Extensions.Options; using MetadataPopulator = System.Func; using RequestDelegateFactoryFunc = System.Func; @@ -386,6 +391,17 @@ namespace Microsoft.AspNetCore.Http.Generated : (httpContext) => httpContext.Request.Query[parameterName]; } + private static Task WriteToResponseAsync(T? value, HttpContext httpContext, JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options) + { + var runtimeType = value?.GetType(); + if (runtimeType is null || jsonTypeInfo.Type == runtimeType || jsonTypeInfo.PolymorphismOptions is not null) + { + return httpContext.Response.WriteAsJsonAsync(value!, jsonTypeInfo); + } + + return httpContext.Response.WriteAsJsonAsync(value!, options.GetTypeInfo(runtimeType)); + } + private static async ValueTask<(bool, T?)> TryResolveBody(HttpContext httpContext, bool allowEmpty) { var feature = httpContext.Features.Get(); diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/Multiple_MapAction_WithParams_StringReturn.generated.txt b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/Multiple_MapAction_WithParams_StringReturn.generated.txt index b60d6a85f7f8..d175a34d3183 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/Multiple_MapAction_WithParams_StringReturn.generated.txt +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/Baselines/Multiple_MapAction_WithParams_StringReturn.generated.txt @@ -93,19 +93,24 @@ namespace Microsoft.AspNetCore.Http.Generated using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; using System.Reflection; + using System.Text.Json; + using System.Text.Json.Serialization.Metadata; using System.Threading.Tasks; using System.IO; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Http.Json; using Microsoft.AspNetCore.Http.Metadata; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Primitives; + using Microsoft.Extensions.Options; using MetadataPopulator = System.Func; using RequestDelegateFactoryFunc = System.Func; @@ -346,6 +351,17 @@ namespace Microsoft.AspNetCore.Http.Generated : (httpContext) => httpContext.Request.Query[parameterName]; } + private static Task WriteToResponseAsync(T? value, HttpContext httpContext, JsonTypeInfo jsonTypeInfo, JsonSerializerOptions options) + { + var runtimeType = value?.GetType(); + if (runtimeType is null || jsonTypeInfo.Type == runtimeType || jsonTypeInfo.PolymorphismOptions is not null) + { + return httpContext.Response.WriteAsJsonAsync(value!, jsonTypeInfo); + } + + return httpContext.Response.WriteAsJsonAsync(value!, options.GetTypeInfo(runtimeType)); + } + private static async ValueTask<(bool, T?)> TryResolveBody(HttpContext httpContext, bool allowEmpty) { var feature = httpContext.Features.Get(); diff --git a/src/Http/Http.Extensions/test/RequestDelegateGenerator/RequestDelegateGeneratorTests.cs b/src/Http/Http.Extensions/test/RequestDelegateGenerator/RequestDelegateGeneratorTests.cs index dc5441e88851..36e725cf1029 100644 --- a/src/Http/Http.Extensions/test/RequestDelegateGenerator/RequestDelegateGeneratorTests.cs +++ b/src/Http/Http.Extensions/test/RequestDelegateGenerator/RequestDelegateGeneratorTests.cs @@ -514,7 +514,11 @@ public async Task MapAction_NoParam_AnyReturn(string source, string expectedBody object GetTodo() => new Todo() { Name = "Test Item"}; app.MapGet("/", GetTodo); """}, - new object[] { """app.MapGet("/", () => TypedResults.Ok(new Todo() { Name = "Test Item"}));""" } + new object[] { """app.MapGet("/", () => TypedResults.Ok(new Todo() { Name = "Test Item"}));""" }, + new object[] { """ +Todo GetTodo() => new Todo() { Name = "Test Item"}; +app.MapGet("/", GetTodo); +"""} }; [Theory] diff --git a/src/Http/samples/MinimalSample/Program.cs b/src/Http/samples/MinimalSample/Program.cs index 274710c979a6..0aa262f38887 100644 --- a/src/Http/samples/MinimalSample/Program.cs +++ b/src/Http/samples/MinimalSample/Program.cs @@ -89,6 +89,7 @@ }); app.MapPost("/todos", (TodoBindable todo) => todo); +app.MapGet("/todos", () => new Todo[] { new Todo(1, "Walk the dog"), new Todo(2, "Come back home") }); app.Run();