Skip to content

Commit

Permalink
Move JsonSerializerOptions initialization logic to a shared helper. (d…
Browse files Browse the repository at this point in the history
  • Loading branch information
eiriktsarpalis authored Jul 31, 2023
1 parent 0203dcb commit 045f9d2
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,7 @@ public static partial class HttpContentJsonExtensions
JsonSerializerOptions? options,
CancellationToken cancellationToken)
{
options ??= JsonSerializerOptions.Default;
options.MakeReadOnly();

var jsonTypeInfo = (JsonTypeInfo<TValue>)options.GetTypeInfo(typeof(TValue));

var jsonTypeInfo = (JsonTypeInfo<TValue>)JsonHelpers.GetJsonTypeInfo(typeof(TValue), options);
return ReadFromJsonAsAsyncEnumerableCore(content, jsonTypeInfo, cancellationToken);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ private JsonContent(
[RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)]
[RequiresDynamicCode(HttpContentJsonExtensions.SerializationDynamicCodeMessage)]
public static JsonContent Create<T>(T inputValue, MediaTypeHeaderValue? mediaType = null, JsonSerializerOptions? options = null)
=> Create(inputValue, GetJsonTypeInfo(typeof(T), options), mediaType);
=> Create(inputValue, JsonHelpers.GetJsonTypeInfo(typeof(T), options), mediaType);

[RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)]
[RequiresDynamicCode(HttpContentJsonExtensions.SerializationDynamicCodeMessage)]
Expand All @@ -44,7 +44,7 @@ public static JsonContent Create(object? inputValue, Type inputType, MediaTypeHe
ThrowHelper.ThrowIfNull(inputType);
EnsureTypeCompatibility(inputValue, inputType);

return new JsonContent(inputValue, GetJsonTypeInfo(inputType, options), mediaType);
return new JsonContent(inputValue, JsonHelpers.GetJsonTypeInfo(inputType, options), mediaType);
}

public static JsonContent Create<T>(T? inputValue, JsonTypeInfo<T> jsonTypeInfo,
Expand Down Expand Up @@ -136,20 +136,6 @@ private async Task SerializeToStreamAsyncCore(Stream targetStream, bool async, C
}
}

[RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)]
[RequiresDynamicCode(HttpContentJsonExtensions.SerializationDynamicCodeMessage)]
private static JsonTypeInfo GetJsonTypeInfo(Type inputType, JsonSerializerOptions? options)
{
Debug.Assert(inputType is not null);

// Ensure the options supports the call to GetTypeInfo
options ??= JsonHelpers.s_defaultSerializerOptions;
options.TypeInfoResolver ??= JsonSerializerOptions.Default.TypeInfoResolver;
options.MakeReadOnly();

return options.GetTypeInfo(inputType);
}

private static void EnsureTypeCompatibility(object? inputValue, Type inputType)
{
if (inputValue is not null && !inputType.IsAssignableFrom(inputValue.GetType()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,33 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization.Metadata;

namespace System.Net.Http.Json
{
internal static class JsonHelpers
{
internal static readonly JsonSerializerOptions s_defaultSerializerOptions = new JsonSerializerOptions(JsonSerializerDefaults.Web);

[RequiresUnreferencedCode(HttpContentJsonExtensions.SerializationUnreferencedCodeMessage)]
[RequiresDynamicCode(HttpContentJsonExtensions.SerializationDynamicCodeMessage)]
internal static JsonTypeInfo GetJsonTypeInfo(Type type, JsonSerializerOptions? options)
{
Debug.Assert(type is not null);

// Resolves JsonTypeInfo metadata using the appropriate JsonSerializerOptions configuration,
// following the semantics of the JsonSerializer reflection methods.
options ??= s_defaultSerializerOptions;
options.TypeInfoResolver ??= JsonSerializerOptions.Default.TypeInfoResolver;
options.MakeReadOnly();

return options.GetTypeInfo(type);
}

internal static MediaTypeHeaderValue GetDefaultMediaType() => new("application/json") { CharSet = "utf-8" };

internal static Encoding? GetEncoding(HttpContent content)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,33 @@ await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync(
server => server.HandleRequestAsync(headers: _headers, content: "null"));
}

[Fact]
public async Task HttpContentAsAsyncEnumerableHonorsWebDefaults()
{
await HttpMessageHandlerLoopbackServer.CreateClientAndServerAsync(
async (handler, uri) =>
{
using (HttpClient client = new HttpClient(handler))
{
var request = new HttpRequestMessage(HttpMethod.Get, uri);
HttpResponseMessage response = await client.SendAsync(request);
int count = 0;
await foreach (Person? per in response.Content.ReadFromJsonAsAsyncEnumerable<Person>())
{
Assert.NotNull(per);
Assert.NotNull(per.Name);
count++;
}
Assert.Equal(People.PeopleCount, count);
}
},
async server =>
{
string jsonResponse = JsonSerializer.Serialize(People.WomenOfProgramming, JsonOptions.DefaultSerializerOptions);
await server.HandleRequestAsync(headers: _headers, content: jsonResponse);
});
}

[Fact]
public async Task TestReadFromJsonAsAsyncEnumerableNoMessageBodyAsync()
{
Expand Down

0 comments on commit 045f9d2

Please sign in to comment.