Skip to content
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

Adding STJ Polymorphism to Result Types #46008

Merged
merged 33 commits into from
Feb 1, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
2143f21
Adding STJ Polymorphism to Result Types
brunolins16 Jan 9, 2023
0c87d13
Merge remote-tracking branch 'upstream/main' into brunolins16/issues/…
brunolins16 Jan 10, 2023
1e048d3
Renaming unittest
brunolins16 Jan 10, 2023
7485673
Adding unit tests
brunolins16 Jan 10, 2023
af1eba8
Adding more unit tests
brunolins16 Jan 10, 2023
84e1c77
Merge remote-tracking branch 'upstream/main' into brunolins16/issues/…
brunolins16 Jan 12, 2023
4a63010
Setting DefaultTypeInfoResolver
brunolins16 Jan 12, 2023
543c338
Merge remote-tracking branch 'upstream/main' into brunolins16/issues/…
brunolins16 Jan 12, 2023
cfbe2fd
Removing ISTrimmable
brunolins16 Jan 12, 2023
8c10b8c
Removing cache
brunolins16 Jan 12, 2023
cabe9c5
Merge remote-tracking branch 'upstream/main' into brunolins16/issues/…
brunolins16 Jan 13, 2023
a4229b3
Clean up
brunolins16 Jan 13, 2023
2be89fc
Avoiding multiple GetTypeInfo calls
brunolins16 Jan 17, 2023
c9ddbea
Merge remote-tracking branch 'upstream/main' into brunolins16/issues/…
brunolins16 Jan 17, 2023
8c09b97
Fixing JsonResult
brunolins16 Jan 18, 2023
52c3b9d
Clean up
brunolins16 Jan 19, 2023
3d7a9f9
clean up
brunolins16 Jan 20, 2023
891d909
Adding Json apis proposal
brunolins16 Jan 20, 2023
1fb0405
Merge remote-tracking branch 'upstream/main' into brunolins16/issues/…
brunolins16 Jan 20, 2023
e854667
Removing name change
brunolins16 Jan 25, 2023
990498c
Merge remote-tracking branch 'upstream/main' into brunolins16/issues/…
brunolins16 Jan 25, 2023
a2a972a
Fixing bad merge
brunolins16 Jan 25, 2023
ae9c2a4
Merge remote-tracking branch 'upstream/main' into brunolins16/issues/…
brunolins16 Jan 27, 2023
c2768f4
Fix build
brunolins16 Jan 27, 2023
610c7b1
PR review
brunolins16 Jan 27, 2023
1930364
PR Feedback
brunolins16 Jan 27, 2023
3b54e1a
Update for the approved API
brunolins16 Jan 30, 2023
205c6c6
PR review
brunolins16 Jan 31, 2023
fba0039
Update TypedResultsTests.cs
brunolins16 Jan 31, 2023
e39d168
Changing IsPolymorphicSafe
brunolins16 Feb 1, 2023
baf9036
Merge remote-tracking branch 'upstream/main' into brunolins16/issues/…
brunolins16 Feb 1, 2023
9df633e
Fixing notnull annotation
brunolins16 Feb 1, 2023
a070575
Remove blank line
brunolins16 Feb 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 0 additions & 28 deletions src/Http/Http.Results/src/HttpResultsHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,6 @@ internal static partial class HttpResultsHelper
internal const string DefaultContentType = "text/plain; charset=utf-8";
private static readonly Encoding DefaultEncoding = Encoding.UTF8;

public static Task WriteResultAsJsonAsync<TValue>(
HttpContext httpContext,
ILogger logger,
TValue? value,
JsonTypeInfo jsonTypeInfo,
string? contentType = null)
{
if (value is null)
{
return Task.CompletedTask;
}

Log.WritingResultAsJson(logger, jsonTypeInfo.Type.Name);
if (jsonTypeInfo is JsonTypeInfo<TValue> genericTypeInfo)
{
// We don't need to box in this case
return httpContext.Response.WriteAsJsonAsync(
value,
genericTypeInfo,
contentType: contentType);
}

return httpContext.Response.WriteAsJsonAsync(
value,
jsonTypeInfo,
contentType: contentType);
}

public static Task WriteResultAsJsonAsync<TValue>(
HttpContext httpContext,
ILogger logger,
Expand Down
52 changes: 26 additions & 26 deletions src/Http/Http.Results/src/JsonHttpResultOfT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

using System.Diagnostics.CodeAnalysis;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
Expand All @@ -16,8 +15,6 @@ namespace Microsoft.AspNetCore.Http.HttpResults;
/// </summary>
public sealed partial class JsonHttpResult<TValue> : IResult, IStatusCodeHttpResult, IValueHttpResult, IValueHttpResult<TValue>, IContentTypeHttpResult
{
private readonly JsonTypeInfo? _jsonTypeInfo;

/// <summary>
/// Initializes a new instance of the <see cref="Json"/> class with the values.
/// </summary>
Expand Down Expand Up @@ -47,21 +44,8 @@ internal JsonHttpResult(TValue? value, JsonSerializerOptions? jsonSerializerOpti
JsonSerializerOptions = jsonSerializerOptions;
}

internal JsonHttpResult(TValue? value, JsonSerializerContext jsonSerializerContext, int? statusCode = null, string? contentType = null)
: this(value, jsonSerializerContext.GetTypeInfo(typeof(TValue))!, statusCode, contentType)
{ }

/// <summary>
/// Initializes a new instance of the <see cref="Json"/> class with the values.
/// </summary>
/// <param name="value">The value to format in the entity body.</param>
/// <param name="jsonTypeInfo">Metadata about the type to convert.</param>
/// <param name="statusCode">The HTTP status code of the response.</param>
/// <param name="contentType">The value for the <c>Content-Type</c> header</param>
internal JsonHttpResult(TValue? value, JsonTypeInfo jsonTypeInfo, int? statusCode = null, string? contentType = null)
internal JsonHttpResult(TValue? value, int? statusCode = null, string? contentType = null)
{
ArgumentNullException.ThrowIfNull(jsonTypeInfo);

Value = value;
ContentType = contentType;

Expand All @@ -72,16 +56,18 @@ internal JsonHttpResult(TValue? value, JsonTypeInfo jsonTypeInfo, int? statusCod
}

StatusCode = statusCode;

_jsonTypeInfo = jsonTypeInfo;
JsonSerializerOptions = jsonTypeInfo.Options;
}

/// <summary>
/// Gets or sets the serializer settings.
/// </summary>
public JsonSerializerOptions? JsonSerializerOptions { get; }

/// <summary>
/// Gets or sets the serializer settings.
/// </summary>
internal JsonTypeInfo? JsonTypeInfo { get; init; }

/// <summary>
/// Gets the object result.
/// </summary>
Expand Down Expand Up @@ -114,14 +100,28 @@ public Task ExecuteAsync(HttpContext httpContext)
httpContext.Response.StatusCode = statusCode;
}

if (_jsonTypeInfo is not null)
if (Value is null)
{
return Task.CompletedTask;
}

if (JsonTypeInfo != null)
{
return HttpResultsHelper.WriteResultAsJsonAsync(
httpContext,
logger,
HttpResultsHelper.Log.WritingResultAsJson(logger, JsonTypeInfo.Type.Name);

if (JsonTypeInfo is JsonTypeInfo<TValue> typedJsonTypeInfo)
{
// We don't need to box here.
return httpContext.Response.WriteAsJsonAsync(
Value,
typedJsonTypeInfo,
contentType: ContentType);

}
return httpContext.Response.WriteAsJsonAsync(
Value,
_jsonTypeInfo,
ContentType);
JsonTypeInfo,
contentType: ContentType);
}

return HttpResultsHelper.WriteResultAsJsonAsync(
Expand Down
10 changes: 5 additions & 5 deletions src/Http/Http.Results/src/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ static Microsoft.AspNetCore.Http.Results.Created(string? uri, object? value) ->
static Microsoft.AspNetCore.Http.Results.Created(System.Uri? uri, object? value) -> Microsoft.AspNetCore.Http.IResult!
static Microsoft.AspNetCore.Http.Results.Created<TValue>(string? uri, TValue? value) -> Microsoft.AspNetCore.Http.IResult!
static Microsoft.AspNetCore.Http.Results.Created<TValue>(System.Uri? uri, TValue? value) -> Microsoft.AspNetCore.Http.IResult!
static Microsoft.AspNetCore.Http.Results.Json(object? data, System.Text.Json.Serialization.JsonSerializerContext! jsonSerializerContext, string? contentType = null, int? statusCode = null) -> Microsoft.AspNetCore.Http.IResult!
static Microsoft.AspNetCore.Http.Results.Json(object? data, System.Text.Json.Serialization.Metadata.JsonTypeInfo! jsonTypeInfo, string? contentType = null, int? statusCode = null) -> Microsoft.AspNetCore.Http.IResult!
static Microsoft.AspNetCore.Http.Results.Json<TValue>(TValue? data, System.Text.Json.Serialization.JsonSerializerContext! jsonSerializerContext, string? contentType = null, int? statusCode = null) -> Microsoft.AspNetCore.Http.IResult!
static Microsoft.AspNetCore.Http.Results.Json<TValue>(TValue? data, System.Text.Json.Serialization.Metadata.JsonTypeInfo! jsonTypeInfo, string? contentType = null, int? statusCode = null) -> Microsoft.AspNetCore.Http.IResult!
static Microsoft.AspNetCore.Http.Results.Json(object? data, System.Type! type, System.Text.Json.Serialization.JsonSerializerContext! context, string? contentType = null, int? statusCode = null) -> Microsoft.AspNetCore.Http.IResult!
static Microsoft.AspNetCore.Http.Results.Json<TValue>(TValue? data, System.Text.Json.Serialization.JsonSerializerContext! context, string? contentType = null, int? statusCode = null) -> Microsoft.AspNetCore.Http.IResult!
static Microsoft.AspNetCore.Http.Results.Json<TValue>(TValue? data, System.Text.Json.Serialization.Metadata.JsonTypeInfo<TValue>! jsonTypeInfo, string? contentType = null, int? statusCode = null) -> Microsoft.AspNetCore.Http.IResult!
static Microsoft.AspNetCore.Http.TypedResults.Created() -> Microsoft.AspNetCore.Http.HttpResults.Created!
static Microsoft.AspNetCore.Http.TypedResults.Created(string? uri) -> Microsoft.AspNetCore.Http.HttpResults.Created!
static Microsoft.AspNetCore.Http.TypedResults.Created(System.Uri? uri) -> Microsoft.AspNetCore.Http.HttpResults.Created!
Expand All @@ -27,5 +27,5 @@ static Microsoft.AspNetCore.Http.TypedResults.Created<TValue>(System.Uri? uri, T
*REMOVED*static Microsoft.AspNetCore.Http.TypedResults.Created(string! uri) -> Microsoft.AspNetCore.Http.HttpResults.Created!
*REMOVED*static Microsoft.AspNetCore.Http.TypedResults.Created<TValue>(System.Uri! uri, TValue? value) -> Microsoft.AspNetCore.Http.HttpResults.Created<TValue>!
*REMOVED*static Microsoft.AspNetCore.Http.TypedResults.Created<TValue>(string! uri, TValue? value) -> Microsoft.AspNetCore.Http.HttpResults.Created<TValue>!
static Microsoft.AspNetCore.Http.TypedResults.Json<TValue>(TValue? data, System.Text.Json.Serialization.JsonSerializerContext! jsonContext, string? contentType = null, int? statusCode = null) -> Microsoft.AspNetCore.Http.HttpResults.JsonHttpResult<TValue>!
static Microsoft.AspNetCore.Http.TypedResults.Json<TValue>(TValue? data, System.Text.Json.Serialization.Metadata.JsonTypeInfo! jsonTypeInfo, string? contentType = null, int? statusCode = null) -> Microsoft.AspNetCore.Http.HttpResults.JsonHttpResult<TValue>!
static Microsoft.AspNetCore.Http.TypedResults.Json<TValue>(TValue? data, System.Text.Json.Serialization.JsonSerializerContext! context, string? contentType = null, int? statusCode = null) -> Microsoft.AspNetCore.Http.HttpResults.JsonHttpResult<TValue>!
static Microsoft.AspNetCore.Http.TypedResults.Json<TValue>(TValue? data, System.Text.Json.Serialization.Metadata.JsonTypeInfo<TValue>! jsonTypeInfo, string? contentType = null, int? statusCode = null) -> Microsoft.AspNetCore.Http.HttpResults.JsonHttpResult<TValue>!
28 changes: 18 additions & 10 deletions src/Http/Http.Results/src/Results.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,24 +201,32 @@ public static IResult Json(object? data, JsonSerializerOptions? options = null,
/// recreating cached data with each call.</remarks>
#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
public static IResult Json(object? data, JsonTypeInfo jsonTypeInfo, string? contentType = null, int? statusCode = null)
#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
=> Json<object>(data, jsonTypeInfo, contentType, statusCode);
{
ArgumentNullException.ThrowIfNull(jsonTypeInfo);
return new JsonHttpResult<object>(data, statusCode, contentType) { JsonTypeInfo = jsonTypeInfo };
}

/// <summary>
/// Creates a <see cref="IResult"/> that serializes the specified <paramref name="data"/> object to JSON.
/// </summary>
/// <param name="data">The object to write as JSON.</param>
/// <param name="jsonSerializerContext">Metadata about the type to convert.</param>
/// <param name="type">The type of object to write.</param>
/// <param name="context">A metadata provider for serializable types.</param>
/// <param name="contentType">The content-type to set on the response.</param>
/// <param name="statusCode">The status code to set on the response.</param>
/// <returns>The created <see cref="JsonHttpResult{TValue}"/> that serializes the specified <paramref name="data"/>
/// as JSON format for the response.</returns>
/// <remarks>Callers should cache an instance of serializer settings to avoid
/// recreating cached data with each call.</remarks>
#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
public static IResult Json(object? data, JsonSerializerContext jsonSerializerContext, string? contentType = null, int? statusCode = null)
#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
=> Json<object>(data, jsonSerializerContext, contentType, statusCode);
public static IResult Json(object? data, Type type, JsonSerializerContext context, string? contentType = null, int? statusCode = null)
{
ArgumentNullException.ThrowIfNull(context);
return new JsonHttpResult<object>(data, statusCode, contentType)
{
JsonTypeInfo = context.GetTypeInfo(type) ?? throw new InvalidOperationException($"Unable to obtain the JsonTypeInfo for type '{type.FullName}' from the context '{context.GetType().FullName}'.")
};
}

/// <summary>
/// Creates a <see cref="IResult"/> that serializes the specified <paramref name="data"/> object to JSON.
Expand Down Expand Up @@ -250,25 +258,25 @@ public static IResult Json<TValue>(TValue? data, JsonSerializerOptions? options
/// <remarks>Callers should cache an instance of serializer settings to avoid
/// recreating cached data with each call.</remarks>
#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
public static IResult Json<TValue>(TValue? data, JsonTypeInfo jsonTypeInfo, string? contentType = null, int? statusCode = null)
public static IResult Json<TValue>(TValue? data, JsonTypeInfo<TValue> jsonTypeInfo, string? contentType = null, int? statusCode = null)
#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
=> TypedResults.Json(data, jsonTypeInfo, contentType, statusCode);

/// <summary>
/// Creates a <see cref="IResult"/> that serializes the specified <paramref name="data"/> object to JSON.
/// </summary>
/// <param name="data">The object to write as JSON.</param>
/// <param name="jsonSerializerContext">Metadata about the type to convert.</param>
/// <param name="context">A metadata provider for serializable types.</param>
/// <param name="contentType">The content-type to set on the response.</param>
/// <param name="statusCode">The status code to set on the response.</param>
/// <returns>The created <see cref="JsonHttpResult{TValue}"/> that serializes the specified <paramref name="data"/>
/// as JSON format for the response.</returns>
/// <remarks>Callers should cache an instance of serializer settings to avoid
/// recreating cached data with each call.</remarks>
#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
public static IResult Json<TValue>(TValue? data, JsonSerializerContext jsonSerializerContext, string? contentType = null, int? statusCode = null)
public static IResult Json<TValue>(TValue? data, JsonSerializerContext context, string? contentType = null, int? statusCode = null)
#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
=> TypedResults.Json(data, jsonSerializerContext, contentType, statusCode);
=> TypedResults.Json(data, context, contentType, statusCode);

/// <summary>
/// Writes the byte-array content to the response.
Expand Down
19 changes: 14 additions & 5 deletions src/Http/Http.Results/src/TypedResults.cs
Original file line number Diff line number Diff line change
Expand Up @@ -209,24 +209,33 @@ public static JsonHttpResult<TValue> Json<TValue>(TValue? data, JsonSerializerOp
/// <returns>The created <see cref="JsonHttpResult{TValue}"/> that serializes the specified <paramref name="data"/>
/// as JSON format for the response.</returns>
#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
public static JsonHttpResult<TValue> Json<TValue>(TValue? data, JsonTypeInfo jsonTypeInfo, string? contentType = null, int? statusCode = null)
public static JsonHttpResult<TValue> Json<TValue>(TValue? data, JsonTypeInfo<TValue> jsonTypeInfo, string? contentType = null, int? statusCode = null)
#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
=> new(data, jsonTypeInfo, statusCode, contentType);
{
ArgumentNullException.ThrowIfNull(jsonTypeInfo);
return new(data, statusCode, contentType) { JsonTypeInfo = jsonTypeInfo };
}

/// <summary>
/// Creates a <see cref="JsonHttpResult{TValue}"/> that serializes the specified <paramref name="data"/> object to JSON.
/// </summary>
/// <typeparam name="TValue">The type of object that will be JSON serialized to the response body.</typeparam>
/// <param name="data">The object to write as JSON.</param>
/// <param name="jsonContext">Metadata about the type to convert.</param>
/// <param name="context">A metadata provider for serializable types.</param>
/// <param name="contentType">The content-type to set on the response.</param>
/// <param name="statusCode">The status code to set on the response.</param>
/// <returns>The created <see cref="JsonHttpResult{TValue}"/> that serializes the specified <paramref name="data"/>
/// as JSON format for the response.</returns>
#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
public static JsonHttpResult<TValue> Json<TValue>(TValue? data, JsonSerializerContext jsonContext, string? contentType = null, int? statusCode = null)
public static JsonHttpResult<TValue> Json<TValue>(TValue? data, JsonSerializerContext context, string? contentType = null, int? statusCode = null)
#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
=> new(data, jsonContext, statusCode, contentType);
{
ArgumentNullException.ThrowIfNull(context);
return new(data, statusCode, contentType)
{
JsonTypeInfo = context.GetTypeInfo(typeof(TValue)) ?? throw new InvalidOperationException($"Unable to obtain the JsonTypeInfo for type '{typeof(TValue).FullName}' from the context '{context.GetType().FullName}'.")
};
}

/// <summary>
/// Writes the byte-array content to the response.
Expand Down
Loading