Skip to content

[API Proposal]: Add new overloads to ReadFromJsonAsync method in HttpContentJsonExtensions #72103

@N0D4N

Description

@N0D4N

Background and motivation

Currently ReadFromJsonAsync method parameters follow pattern (with parameter names skipped): this HttpContent, Type/*if it isn't generic overload*/, JsonSerializerOptions? = null /*or JsonSerializerContext or JsonTypeInfo<T>*/, CancellationToken = default

public static System.Threading.Tasks.Task<object?> ReadFromJsonAsync(this System.Net.Http.HttpContent content, System.Type type, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public static System.Threading.Tasks.Task<object?> ReadFromJsonAsync(this System.Net.Http.HttpContent content, System.Type type, System.Text.Json.Serialization.JsonSerializerContext context, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCodeAttribute("JSON serialization and deserialization might require types that cannot be statically analyzed. Use the overload that takes a JsonTypeInfo or JsonSerializerContext, or make sure all of the required types are preserved.")]
public static System.Threading.Tasks.Task<T?> ReadFromJsonAsync<T>(this System.Net.Http.HttpContent content, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public static System.Threading.Tasks.Task<T?> ReadFromJsonAsync<T>(this System.Net.Http.HttpContent content, System.Text.Json.Serialization.Metadata.JsonTypeInfo<T> jsonTypeInfo, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }

Which makes impossible calling ReadFromJsonAsync method without specifying JsonSerializerOptions/JsonSerializerContext/JsonTypeInfo<T> parameters, but with passing CancellationToken parameter. Prior to S.T.J source-gen it was possible via calling for example content.ReadFromJsonAsync<MyClass>(null, cancellationToken). However with introducing json source-gen now this is impossible since compiler can't deduce type behind null passed as param, since JsonSerializerOptions overload was the only one, and now it isn't. So now user needs to specify parameter of null like this content.ReadFromJsonAsync<MyClass>((JsonSerializerOptions?)null, cancellationToken) which is additional typing, and doesn't look pleasant.

API Proposal

namespace System.Net.Http.Json;

public static partial class HttpContentJsonExtensions
{
        public static Task<object?> ReadFromJsonAsync(this HttpContent content, Type type, CancellationToken cancellationToken = default) { throw null; }
        public static Task<T?> ReadFromJsonAsync<T>(this HttpContent content, CancellationToken cancellationToken = default) { throw null; }
}

It should also be noted that HttpClientJsonExtensions methods overloads already follow the same pattern as proposed of skipping nullable JsonSerializerOptions parameter:

public static System.Threading.Tasks.Task<TValue?> DeleteFromJsonAsync<TValue>(this System.Net.Http.HttpClient client, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("Uri")] string? requestUri, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }

API Usage

public async Task<MyClass> MyMethodAsync(HttpRequestMessage message, CancellationToken cancellationToken)
{
	// do some work
	return await message.Content.ReadAsJsonAsync(cancellationToken);
	// compared to
	// return await message.Content.ReadFromJsonAsync<MyClass>((JsonSerializerOptions?)null, cancellationToken)
}

Alternative Designs

Can't think of any.

Risks

Can't think of any, since it follows the same pattern present as in other class.

Metadata

Metadata

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions