public static Task <T?> ReadFromJsonAsync <T>(this HttpContent content, JsonSerializerOptions?options = null, CancellationToken cancellationToken = default)
        {
            if (content is null)
            {
                throw new ArgumentNullException(nameof(content));
            }

            Encoding?sourceEncoding = JsonHelpers.GetEncoding(content.Headers.ContentType?.CharSet);

            return(ReadFromJsonAsyncCore <T>(content, sourceEncoding, options, cancellationToken));
        }
Пример #2
0
        public static Task <object?> ReadFromJsonAsync(this HttpContent content, Type type, JsonSerializerContext context, CancellationToken cancellationToken = default)
        {
            if (content == null)
            {
                throw new ArgumentNullException(nameof(content));
            }

            Encoding?sourceEncoding = JsonHelpers.GetEncoding(content.Headers.ContentType?.CharSet);

            return(ReadFromJsonAsyncCore(content, type, sourceEncoding, context, cancellationToken));
        }
Пример #3
0
        public static Task <object?> ReadFromJsonAsync(this HttpContent content, [DynamicallyAccessedMembers(JsonHelpers.DeserializationMemberTypes)] Type type, JsonSerializerOptions?options = null, CancellationToken cancellationToken = default)
        {
            if (content == null)
            {
                throw new ArgumentNullException(nameof(content));
            }

            Encoding?sourceEncoding = JsonHelpers.GetEncoding(content.Headers.ContentType?.CharSet);

            return(ReadFromJsonAsyncCore(content, type, sourceEncoding, options, cancellationToken));
        }
Пример #4
0
        private async Task SerializeToStreamAsyncCore(Stream targetStream, bool async, CancellationToken cancellationToken)
        {
            Encoding?targetEncoding = JsonHelpers.GetEncoding(Headers.ContentType?.CharSet);

            // Wrap provided stream into a transcoding stream that buffers the data transcoded from utf-8 to the targetEncoding.
            if (targetEncoding != null && targetEncoding != Encoding.UTF8)
            {
#if NETCOREAPP
                Stream transcodingStream = Encoding.CreateTranscodingStream(targetStream, targetEncoding, Encoding.UTF8, leaveOpen: true);
                try
                {
                    if (async)
                    {
                        await SerializeAsyncHelper(transcodingStream, Value, ObjectType, _jsonSerializerOptions, cancellationToken).ConfigureAwait(false);
                    }
                    else
                    {
                        // Have to use Utf8JsonWriter because JsonSerializer doesn't support sync serialization into stream directly.
                        // ToDo: Remove Utf8JsonWriter usage after https://github.com/dotnet/runtime/issues/1574
                        using var writer = new Utf8JsonWriter(transcodingStream);
                        SerializeHelper(writer, Value, ObjectType, _jsonSerializerOptions);
                    }
                }
                finally
                {
                    // Dispose/DisposeAsync will flush any partial write buffers. In practice our partial write
                    // buffers should be empty as we expect JsonSerializer to emit only well-formed UTF-8 data.
                    if (async)
                    {
                        await transcodingStream.DisposeAsync().ConfigureAwait(false);
                    }
                    else
                    {
                        transcodingStream.Dispose();
                    }
                }
#else
                Debug.Assert(async);

                using (TranscodingWriteStream transcodingStream = new TranscodingWriteStream(targetStream, targetEncoding))
                {
                    await SerializeAsyncHelper(transcodingStream, Value, ObjectType, _jsonSerializerOptions, cancellationToken).ConfigureAwait(false);

                    // The transcoding streams use Encoders and Decoders that have internal buffers. We need to flush these
                    // when there is no more data to be written. Stream.FlushAsync isn't suitable since it's
                    // acceptable to Flush a Stream (multiple times) prior to completion.
                    await transcodingStream.FinalWriteAsync(cancellationToken).ConfigureAwait(false);
                }
#endif
            }
            else
            {
                if (async)
                {
                    await SerializeAsyncHelper(targetStream, Value, ObjectType, _jsonSerializerOptions, cancellationToken).ConfigureAwait(false);
                }
                else
                {
#if NETCOREAPP
                    // Have to use Utf8JsonWriter because JsonSerializer doesn't support sync serialization into stream directly.
                    // ToDo: Remove Utf8JsonWriter usage after https://github.com/dotnet/runtime/issues/1574
                    using var writer = new Utf8JsonWriter(targetStream);
                    SerializeHelper(writer, Value, ObjectType, _jsonSerializerOptions);
#else
                    Debug.Fail("Synchronous serialization is only supported since .NET 5.0");
#endif
                }
            }
Пример #5
0
        /// <summary>
        /// Based on <see cref="JsonContent.SerializeToStreamAsyncCore(Stream, bool, CancellationToken)"/>.
        /// The difference is that this implementation calls overloads of <see cref="JsonSerializer"/> that take type metadata directly.
        /// This is done to avoid rooting unused, built-in <see cref="System.Text.Json.Serialization.JsonConverter"/>s and reflection-based
        /// warm-up logic (to reduce app size and be trim-friendly), post trimming.
        /// </summary>
        private async Task SerializeToStreamAsyncCore(Stream targetStream, bool async, CancellationToken cancellationToken)
        {
            Encoding?targetEncoding = JsonHelpers.GetEncoding(Headers.ContentType?.CharSet);

            // Wrap provided stream into a transcoding stream that buffers the data transcoded from utf-8 to the targetEncoding.
            if (targetEncoding != null && targetEncoding != Encoding.UTF8)
            {
#if NETCOREAPP
                Stream transcodingStream = Encoding.CreateTranscodingStream(targetStream, targetEncoding, Encoding.UTF8, leaveOpen: true);
                try
                {
                    if (async)
                    {
                        await JsonSerializer.SerializeAsync(transcodingStream, _typedValue, _typeInfo, cancellationToken).ConfigureAwait(false);
                    }
                    else
                    {
                        JsonSerializer.Serialize(transcodingStream, _typedValue, _typeInfo);
                    }
                }
                finally
                {
                    // Dispose/DisposeAsync will flush any partial write buffers. In practice our partial write
                    // buffers should be empty as we expect JsonSerializer to emit only well-formed UTF-8 data.
                    if (async)
                    {
                        await transcodingStream.DisposeAsync().ConfigureAwait(false);
                    }
                    else
                    {
                        transcodingStream.Dispose();
                    }
                }
#else
                Debug.Assert(async);

                using (TranscodingWriteStream transcodingStream = new TranscodingWriteStream(targetStream, targetEncoding))
                {
                    await JsonSerializer.SerializeAsync(transcodingStream, _typedValue, _typeInfo, cancellationToken).ConfigureAwait(false);

                    // The transcoding streams use Encoders and Decoders that have internal buffers. We need to flush these
                    // when there is no more data to be written. Stream.FlushAsync isn't suitable since it's
                    // acceptable to Flush a Stream (multiple times) prior to completion.
                    await transcodingStream.FinalWriteAsync(cancellationToken).ConfigureAwait(false);
                }
#endif
            }
            else
            {
                if (async)
                {
                    await JsonSerializer.SerializeAsync(targetStream, _typedValue, _typeInfo, cancellationToken).ConfigureAwait(false);
                }
                else
                {
#if NETCOREAPP
                    JsonSerializer.Serialize(targetStream, _typedValue, _typeInfo);
#else
                    Debug.Fail("Synchronous serialization is only supported since .NET 5.0");
#endif
                }
            }
        }