Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

[release/3.1] Add new System.Net.Http.Json project/namespace #42879

Closed
wants to merge 25 commits into from

Conversation

jozkee
Copy link
Member

@jozkee jozkee commented Mar 17, 2020

Port of dotnet/runtime#33459
Note that the runtime PR is still open, so please add all feedback that is not related to release/3.1 there (all new commits on that PR will be ported into here as well)

Description

Serializing and deserializing JSON payloads from the network is a very common operation for clients, especially in the upcoming Blazor environment. Right now, sending a JSON payload to the server requires multiple lines of code, which will be a major speed bump for those customers. We'd like to add extension methods on top of HttpClient that allows doing those operations with a single method call.

This creates a package that targets netstandard2.0 only.
This does not ship inbox in this branch.

Customer Impact

This provides a solution that serves as a replacement of the old-fashioned Microsoft.AspNet.WebApi.Client, that is compatible with netstandard2.0 and can be used by Blazor WebAssembly apps.

Regression

None.
This is a brand new project.

Testing

Added unit tests to verify correct behavior of API surface.
Added unit tests to verify correct behavior of transcoding semantics.

Risk

This is a whole new API that has not even shipped as a preview in runtime, and it is still on active development.

@joperezr
Copy link
Member

cc: @ericstj @jeffhandley

@joperezr
Copy link
Member

cc: @terrajobst

@ericstj
Copy link
Member

ericstj commented Mar 17, 2020

All the failures appear to be:

System.ArgumentException : The output byte buffer is too small to contain the encoded data, encoding 'Unicode (UTF-8)' fallback 'System.Text.EncoderReplacementFallback'.\r\nParameter name: bytes

@joperezr
Copy link
Member

@ericstj yeah we actually knew before hand that those tests would fail, he was in the middle of working on fixing them when we started porting the branch to release/3.1, once he fixes all those in runtime repo we will port the fix back here. I'm looking into the packaging test failures, as they are related to the new package.

public System.Type ObjectType { get { throw null; } }
public object? Value { get { throw null; } }
public static System.Net.Http.Json.JsonContent Create(object? inputValue, System.Type inputType, System.Net.Http.Headers.MediaTypeHeaderValue mediaType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
public static System.Net.Http.Json.JsonContent Create<T>(T value, System.Net.Http.Headers.MediaTypeHeaderValue mediaType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both here and above, mediaType is supposed to have = null, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not what we agreed on API review, but I do agree on the need to have an optional mediaType or an overload that does not take it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe it is just missing in the spec.
dotnet/runtime#33566 (comment)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not what we agreed on API review

https://youtu.be/_AHbjIS8_0I?t=4272

public System.Type ObjectType { get { throw null; } }
public object? Value { get { throw null; } }
public static System.Net.Http.Json.JsonContent Create(object? inputValue, System.Type inputType, System.Net.Http.Headers.MediaTypeHeaderValue mediaType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
public static System.Net.Http.Json.JsonContent Create<T>(T value, System.Net.Http.Headers.MediaTypeHeaderValue mediaType, System.Text.Json.JsonSerializerOptions? options = null) { throw null; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have T value and object? inputValue... should they have the same name?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree.

@leecow leecow added Servicing-approved Approved for servicing release and removed Servicing-consider Issue for next servicing release review labels Mar 17, 2020

using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("System.Net.Http.Json.Functional.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001004b86c4cb78549b34bab61a3b1800e23bfeb5b3ec390074041536a7e3cbd97f5f04cf0f857155a8928eaa29ebfd11cfbbad3ba70efea7bda3226c6a8d370a4cd303f714486b6ebc225985a638471e6ef571cc92a4613c00b8fa65d61ccee0cbe5f36330c9a01f4183559f1bef24cc2917c6d913e3a541333a1d05d9bed22b38cb")]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We try very hard not to use InternalsVisibleTo; we've stamped them out in most places, and I would like not to add more. . There are a variety of reasons for this but, for example, this will prevent trimming anything in the assembly. Can we please remove this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I can workaround this. I just added it since the original code on aspnetcore is being tested this way.

{
public static Task<object?> ReadFromJsonAsync(this HttpContent content, Type type, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default)
{
return ReadFromJsonAsyncCore(content, type, options, cancellationToken);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: elsewhere we've used expression-body members for one-liners, but here we're not?


private JsonContent(object? value, Type inputType, MediaTypeHeaderValue mediaType, JsonSerializerOptions? options)
{
if (mediaType == null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we were allowing mediaType to be null, and actually making it an optional parameter (defaulting to null) to avoid needing additional Create overloads that didn't take it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case we need to mark it as such (MediaTypeHeaderValue?).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that was the decision in API review as far as I remember: MediaTypeHeaderValue? mediaType = null.

@joperezr
Copy link
Member

joperezr commented Mar 17, 2020

@ericstj can you please take a look to aab639f to make sure that the suppression added and the package index is what you expect?

@joperezr joperezr added the * NO MERGE * The PR is not ready for merge yet (see discussion for detailed reasons) label Mar 17, 2020
@joperezr
Copy link
Member

Adding No Merge label to wait till the runtime PR has been approved and checked in before we merge this one.

{
public static partial class HttpClientJsonExtensions
{
public static System.Threading.Tasks.Task<object?> GetFromJsonAsync(this System.Net.Http.HttpClient client, string? requestUri, System.Type type, System.Text.Json.JsonSerializerOptions? options = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stephentoub Should we call it Type returnType instead? here and for HttpContentJsonExtensions.ReadFromJsonAsync since that's the name of the param in JsonSerializer.Deserialize.

https://docs.microsoft.com/en-us/dotnet/api/system.text.json.jsonserializer.deserialize?view=netcore-3.1#System_Text_Json_JsonSerializer_Deserialize_System_String_System_Type_System_Text_Json_JsonSerializerOptions_

@ericstj
Copy link
Member

ericstj commented Mar 17, 2020

Why is code-review on content and test fixing happening in release? Is this specific to release code? If not, polish this and finish in master first. Release PR should be cherry-pick and whatever minor changes need to be done to port. I wouldn't expect tons of feedback here, it is not efficient to do that in two places.

ArrayPool<byte>.Shared.Return(_byteBuffer.Array);

Debug.Assert(_overflowBuffer.Array != null);
ArrayPool<byte>.Shared.Return(_overflowBuffer.Array);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should null out the various buffer fields. Otherwise, misuse of this stream could end up accessing arrays that have already been returned to the pool.

@stephentoub
Copy link
Member

stephentoub commented Mar 17, 2020

Why is code-review on content and test fixing happening in release?

Simply because this is the PR I heard you refer to in the meeting just now / you sent out a link to. I didn't receive any notifications that the other PR in dotnet/runtime had been updated, and saw this as being newer than the last time I looked at dotnet/runtime.

@jozkee
Copy link
Member Author

jozkee commented Mar 17, 2020

@stephentoub for the record, the PR in dotnet/runtime already contains the set of changes that you are reviewing here.

@stephentoub
Copy link
Member

stephentoub commented Mar 17, 2020

Ok. I didn't receive a notification that it had been updated. I only received a link from Eric to this PR. Hence my commenting here.

I'm halfway through. How would you like me to proceed?

@jozkee
Copy link
Member Author

jozkee commented Mar 17, 2020

Just to keep PR comments centralized, you can continue on dotnet/runtime#33459

I will address the feedback on both PRs.

<!-- Permit inbox revsion of assemblies that are part of shared framework but also ship as packages. This will
make sure other packages that have a reference to them will carry a package reference to the latest serviced
version. -->
<ValidatePackageSuppression Include="PermitInbox">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this required? Can you please share the error message you were getting?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The private transport package was failing due to a version inconsistency, System.Text.Json was expected to be inbox with version 4.0.1.0 but was found to have 4.0.1.1. Here is the error message I got:

C:\Users\joperezr\.nuget\packages\microsoft.dotnet.build.tasks.packaging\1.0.0-beta.20113.5\build\Packaging.targets(1161,5): error : File System.Text.Json, version 4.0.1.1 was included framework package Microsoft.Private.CoreFx.NETCoreApp/4.7.0-dev.20167.1 but that version is not considered inbox in package index F:\git\corefx\pkg\Microsoft.Private.PackageBaseline\packageIndex.json.  Please add it with appropriate InboxOn entry for netcoreapp3.1 or suppress this message with PermitInbox suppression. [F:\git\corefx\pkg\Microsoft.Private.CoreFx.NETCoreApp\Microsoft.Private.CoreFx.NETCoreApp.pkgproj]

@joperezr
Copy link
Member

Closing this PR in favor of #42889 which is targeting the new branch that was created for this project.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Net.Http area-System.Text.Json * NO MERGE * The PR is not ready for merge yet (see discussion for detailed reasons) Servicing-approved Approved for servicing release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants