-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Add JsonContent.Create overloads that accept JsonTypeInfo. #51544
Comments
Tagging subscribers to this area: @eiriktsarpalis, @layomia Issue DetailsFollowing up from #51528, implement the following APIs approved in #45448. The corresponding namespace System.Net.Http.Json
{
public static partial class HttpClientJsonExtensions
{
public static Task<HttpResponseMessage> PostAsJsonAsync<TValue>(this HttpClient client, string? requestUri, TValue value, JsonTypeInfo<TValue> jsonTypeInfo, CancellationToken cancellationToken = default(CancellationToken)) { throw null; }
public static Task<HttpResponseMessage> PostAsJsonAsync<TValue>(this HttpClient client, System.Uri? requestUri, TValue value, JsonTypeInfo<TValue> jsonTypeInfo, CancellationToken cancellationToken = default(CancellationToken)) { throw null; }
public static Task<HttpResponseMessage> PutAsJsonAsync<TValue>(this HttpClient client, string? requestUri, TValue value, JsonTypeInfo<TValue> jsonTypeInfo, CancellationToken cancellationToken = default(CancellationToken)) { throw null; }
public static Task<HttpResponseMessage> PutAsJsonAsync<TValue>(this HttpClient client, System.Uri? requestUri, TValue value, JsonTypeInfo<TValue> jsonTypeInfo, CancellationToken cancellationToken = default(CancellationToken)) { throw null; }
}
public sealed partial class JsonContent : HttpContent
{
public static JsonContent Create(object? inputValue, Type inputType, JsonSerializerContext context, MediaTypeHeaderValue mediaType = null) { throw null; }
public static JsonContent Create<T>(T inputValue, JsonTypeInfo<T> jsonValueInfo, MediaTypeHeaderValue mediaType = null) { throw null; }
}
} The challenge here is making these methods linker/size friendly, since the underlying The solution could be to add new ( Currently targeting preview 5 to get this work in. cc @eerhardt, @CoffeeFlux, @jozkee.
|
namespace System.Net.Http.Json
{
public sealed partial class JsonContent<TValue> : JsonContent
{
internal JsonContent() { }
public TValue? Value { get { throw null; } }
}
partial class JsonContent
{
public static JsonContent<object?> Create(object? inputValue, Type inputType, JsonSerializerContext context, MediaTypeHeaderValue? mediaType = null) { throw null; }
public static JsonContent<TValue> Create<TValue>(TValue? inputValue, JsonTypeInfo<TValue> jsonTypeInfo, MediaTypeHeaderValue? mediaType = null) { throw null; }
}
} namespace System.Net.Http.Json
{
- public sealed partial class JsonContent
+ public abstract partial class JsonContent
{
internal JsonContent();
}
+ internal sealed partial class ReflectionBasedJsonContent : JsonContent { ... }
} |
Triage: we can do this in .NET 7. |
Question: what necessitates needing to make partial class JsonContent
{
public static JsonContent Create(object? inputValue, Type inputType, JsonSerializerContext context, MediaTypeHeaderValue? mediaType = null) { throw null; }
public static JsonContent Create<TValue>(TValue? inputValue, JsonTypeInfo<TValue> jsonTypeInfo, MediaTypeHeaderValue? mediaType = null) { throw null; }
} |
Request body serialization improvements are blocked by dotnet/runtime#60378 and dotnet/runtime#51544
…urcegen Request body serialization improvements are blocked by dotnet/runtime#60378 and dotnet/runtime#51544
@eiriktsarpalis IL trimming: we need a separate content type which does not derive from |
I was just following this blog post which still lists the new Might be worth updating the blog post to remove them. I'd have left a comment on the blog, but comments are closed. |
…urcegen Request body serialization improvements are blocked by dotnet/runtime#60378 and dotnet/runtime#51544
I've updated the blog post - we should add these APIs in .NET 7. |
This issue seems to have been postponed a few times. Is this planned for .NET8 or should I be looking for workarounds (e.g. using StringContent) instead? |
It's currently in the |
Ok, too bad. Is there a recommended workaround? Like using |
You could use the existing overloads accepting |
Hi, when think about implementation, I have question about the new class |
Is this postponed simply due to team bandwidth and you'd be interested in accepting a community contribution that meets the accepted API surface on this issue? Or are there other considerations? I ask because this would be very helpful for https://github.com/CenterEdge/Yardarm so I'd be happy to do the work to get it included. |
It's also lack of bandwidth, but it's also the fact that the proposal was approved two years ago and is probably no longer fit for purpose given the recent additions in contract customisation:
We should instead consider exposing overloads that do not force linker warnings at all: public sealed partial class JsonContent : HttpContent
{
public static JsonContent Create(TValue? inputValue, JsonTypeInfo<TValue> jsonTypeInfo, MediaTypeHeaderValue? mediaType = null);
public static JsonContent Create(object? inputValue, JsonTypeInfo typeInfo, MediaTypeHeaderValue? mediaType = null);
} |
I tried it like you recommended:
However the same build warning persists, because the same method is still being called, just with an options object instead of null. I don't see another overload I could use instead.
|
@tipa it's unfortunate, but all serialization overloads accepting a |
Looks good as proposed (modulo typos) namespace System.Net.Http.Json
{
public partial class JsonContent
{
public static JsonContent Create<TValue>(TValue? inputValue, JsonTypeInfo<TValue> jsonTypeInfo, MediaTypeHeaderValue? mediaType = null);
public static JsonContent Create(object? inputValue, JsonTypeInfo jsonTypeInfo, MediaTypeHeaderValue? mediaType = null);
}
} |
Great to see this API approved! I'd still love to take this on if that helps, just let me know. I don't want to cross streams if someone is planning to take this internally. |
Feel free to pick it up @brantburnett |
EDIT New proposal can be found here: #51544 (comment)
Details
Background
The existing
JsonContent
type inSystem.Net.Http.Json
uses existingJsonSerializerOptions
-basedJsonSerializer.Serialize(Async)
overloads which root reflection code and all built-in STJ converters (even when not needed in an app). We should add a new type that uses newJsonSerializerContext
-based overloads, which are AOT-friendly and allow for a smaller app. Also the existing type has been marked as "requires unreferenced code", so it is beneficial to provide an alternative which is trim-friendly.API Proposal
We should also expose static
Create
methods for these types to the existingJsonContent
:The new create methods should go on
JsonContent
- if we put them onJsonContent<TValue>
, then it will be possible for users to write awkward code like this:Usage
Just like the existing
JsonContent
type,JsonContent<TValue>
can be used when building aHttpResponseMessage
based on JSON. The difference is that now the JSON will be serialized in a trim-safe way which is also optimized for app size:Q/A
Can
JsonContent<TValue>
derive fromJsonContent<T>
?It's better not to do this, because the ILLinker won't be able to trim away reflection-based code and extra
JsonConverter
s used by the existingJsonContent
type. The underlying infrastructure for serializing the JSON content is based on overriding virtual methods. Making the newJsonContent<TValue>
type derive from the existing type is bad because the linker will preserve the virtual and override methods of called methods in the hierarchy, because it doesn't know which one will be called at run-time. This is discussed in more detail here.The text was updated successfully, but these errors were encountered: