-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Making JsonOptions
AOT/Trimmer-safe with EnsureJsonTrimmability switch
#45886
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
de329aa
704c795
1c777f5
2a997e5
e160ba9
afd597e
04f35db
5b432db
6ee0008
e3521da
4048eae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -32,13 +32,14 @@ public static class HttpRequestJsonExtensions | |
/// <param name="request">The request to read from.</param> | ||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param> | ||
/// <returns>The task object representing the asynchronous operation.</returns> | ||
[RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why havne't we done this for all methods in this class? For example, public static async ValueTask<TValue?> ReadFromJsonAsync<TValue>(
this HttpRequest request,
JsonSerializerOptions? options,
CancellationToken cancellationToken = default) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar question for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When the user provides a |
||
[RequiresDynamicCode(RequiresDynamicCodeMessage)] | ||
public static ValueTask<TValue?> ReadFromJsonAsync<TValue>( | ||
this HttpRequest request, | ||
CancellationToken cancellationToken = default) | ||
{ | ||
return request.ReadFromJsonAsync<TValue>(options: null, cancellationToken); | ||
ArgumentNullException.ThrowIfNull(request); | ||
|
||
var options = ResolveSerializerOptions(request.HttpContext); | ||
return request.ReadFromJsonAsync(jsonTypeInfo: (JsonTypeInfo<TValue>)options.GetTypeInfo(typeof(TValue)), cancellationToken); | ||
} | ||
|
||
/// <summary> | ||
|
@@ -166,14 +167,15 @@ public static class HttpRequestJsonExtensions | |
/// <param name="type">The type of object to read.</param> | ||
/// <param name="cancellationToken">A <see cref="CancellationToken"/> used to cancel the operation.</param> | ||
/// <returns>The task object representing the asynchronous operation.</returns> | ||
[RequiresUnreferencedCode(RequiresUnreferencedCodeMessage)] | ||
[RequiresDynamicCode(RequiresDynamicCodeMessage)] | ||
public static ValueTask<object?> ReadFromJsonAsync( | ||
this HttpRequest request, | ||
Type type, | ||
CancellationToken cancellationToken = default) | ||
{ | ||
return request.ReadFromJsonAsync(type, options: null, cancellationToken); | ||
ArgumentNullException.ThrowIfNull(request); | ||
|
||
var options = ResolveSerializerOptions(request.HttpContext); | ||
return request.ReadFromJsonAsync(jsonTypeInfo: options.GetTypeInfo(type), cancellationToken); | ||
} | ||
|
||
/// <summary> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
using System.Text.Encodings.Web; | ||
using System.Text.Json; | ||
using System.Text.Json.Serialization.Metadata; | ||
using Microsoft.AspNetCore.Internal; | ||
|
||
#nullable enable | ||
|
||
|
@@ -26,7 +27,7 @@ public class JsonOptions | |
// The JsonSerializerOptions.GetTypeInfo method is called directly and needs a defined resolver | ||
// setting the default resolver (reflection-based) but the user can overwrite it directly or calling | ||
// .AddContext<TContext>() | ||
TypeInfoResolver = CreateDefaultTypeResolver() | ||
TypeInfoResolver = TrimmingAppContextSwitches.EnsureJsonTrimmability ? null : CreateDefaultTypeResolver() | ||
}; | ||
|
||
// Use a copy so the defaults are not modified. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What's the plan for the suppressions on line 39-44? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For now, they will suppress in the |
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<linker> | ||
<assembly fullname="Microsoft.AspNetCore.Http.Extensions"> | ||
<type fullname="Microsoft.AspNetCore.Internal.TrimmingAppContextSwitches"> | ||
<method signature="System.Boolean get_EnsureJsonTrimmability()" body="stub" value="true" feature="Microsoft.AspNetCore.EnsureJsonTrimmability" featurevalue="true" /> | ||
</type> | ||
</assembly> | ||
</linker> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// 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.Json.Serialization.Metadata; | ||
using Microsoft.AspNetCore.Http.Json; | ||
using Microsoft.AspNetCore.Testing; | ||
using Microsoft.DotNet.RemoteExecutor; | ||
|
||
namespace Microsoft.AspNetCore.Http.Extensions; | ||
|
||
public class JsonOptionsTests | ||
{ | ||
[ConditionalFact] | ||
[RemoteExecutionSupported] | ||
public void DefaultSerializerOptions_SetsTypeInfoResolverNull_WhenEnsureJsonTrimmabilityTrue() | ||
{ | ||
var options = new RemoteInvokeOptions(); | ||
options.RuntimeConfigurationOptions.Add("Microsoft.AspNetCore.EnsureJsonTrimmability", true.ToString()); | ||
|
||
using var remoteHandle = RemoteExecutor.Invoke(static () => | ||
{ | ||
// Arrange | ||
var options = JsonOptions.DefaultSerializerOptions; | ||
|
||
// Assert | ||
Assert.Null(options.TypeInfoResolver); | ||
}, options); | ||
} | ||
|
||
[ConditionalFact] | ||
[RemoteExecutionSupported] | ||
public void DefaultSerializerOptions_SetsTypeInfoResolverToDefault_WhenEnsureJsonTrimmabilityFalse() | ||
{ | ||
var options = new RemoteInvokeOptions(); | ||
options.RuntimeConfigurationOptions.Add("Microsoft.AspNetCore.EnsureJsonTrimmability", false.ToString()); | ||
|
||
using var remoteHandle = RemoteExecutor.Invoke(static () => | ||
{ | ||
// Arrange | ||
var options = JsonOptions.DefaultSerializerOptions; | ||
|
||
// Assert | ||
Assert.NotNull(options.TypeInfoResolver); | ||
Assert.IsType<DefaultJsonTypeInfoResolver>(options.TypeInfoResolver); | ||
}, options); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<linker> | ||
<assembly fullname="Microsoft.AspNetCore.Mvc.Core"> | ||
<type fullname="Microsoft.AspNetCore.Internal.TrimmingAppContextSwitches"> | ||
<method signature="System.Boolean get_EnsureJsonTrimmability()" body="stub" value="true" feature="Microsoft.AspNetCore.EnsureJsonTrimmability" featurevalue="true" /> | ||
brunolins16 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
</type> | ||
</assembly> | ||
</linker> |
Uh oh!
There was an error while loading. Please reload this page.