/// <inheritdoc />
        public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (selectedEncoding == null)
            {
                throw new ArgumentNullException(nameof(selectedEncoding));
            }

            var response = context.HttpContext.Response;

            using (var writer = context.WriterFactory(response.Body, selectedEncoding))
            {
                using (var jsonWriter = CreateJsonWriter(writer))
                {
                    var jsonSerializer = CreateJsonSerializer();
                    jsonSerializer.Serialize(jsonWriter, context.Object);
                }

                // Perf: call FlushAsync to call WriteAsync on the stream with any content left in the TextWriter's
                // buffers. This is better than just letting dispose handle it (which would result in a synchronous
                // write).
                await writer.FlushAsync();
            }
        }
Exemple #2
0
        /// <inheritdoc />
        public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (selectedEncoding == null)
            {
                throw new ArgumentNullException(nameof(selectedEncoding));
            }

            // Compat mode for derived options
            _jsonOptions ??= context.HttpContext.RequestServices.GetRequiredService <IOptions <MvcNewtonsoftJsonOptions> >().Value;

            var response = context.HttpContext.Response;

            var responseStream = response.Body;
            FileBufferingWriteStream?fileBufferingWriteStream = null;

            if (!_mvcOptions.SuppressOutputFormatterBuffering)
            {
                fileBufferingWriteStream = new FileBufferingWriteStream(_jsonOptions.OutputFormatterMemoryBufferThreshold);
                responseStream           = fileBufferingWriteStream;
            }

            var value = context.Object;

            if (value is not null && _asyncEnumerableReaderFactory.TryGetReader(value.GetType(), out var reader))
            {
                _logger ??= context.HttpContext.RequestServices.GetRequiredService <ILogger <NewtonsoftJsonOutputFormatter> >();
                Log.BufferingAsyncEnumerable(_logger, value);
                value = await reader(value);
            }

            try
            {
                await using (var writer = context.WriterFactory(responseStream, selectedEncoding))
                {
                    using var jsonWriter = CreateJsonWriter(writer);
                    var jsonSerializer = CreateJsonSerializer(context);
                    jsonSerializer.Serialize(jsonWriter, value);
                }

                if (fileBufferingWriteStream != null)
                {
                    response.ContentLength = fileBufferingWriteStream.Length;
                    await fileBufferingWriteStream.DrainBufferAsync(response.BodyWriter);
                }
            }
            finally
            {
                if (fileBufferingWriteStream != null)
                {
                    await fileBufferingWriteStream.DisposeAsync();
                }
            }
        }
        /// <inheritdoc />
        public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (selectedEncoding == null)
            {
                throw new ArgumentNullException(nameof(selectedEncoding));
            }

            var writerSettings = WriterSettings.Clone();

            writerSettings.Encoding = selectedEncoding;

            // Wrap the object only if there is a wrapping type.
            var value        = context.Object;
            var wrappingType = GetSerializableType(context.ObjectType);

            if (wrappingType != null && wrappingType != context.ObjectType)
            {
                var wrapperProvider = WrapperProviderFactories.GetWrapperProvider(new WrapperProviderContext(
                                                                                      declaredType: context.ObjectType,
                                                                                      isSerialization: true));

                value = wrapperProvider.Wrap(value);
            }

            var xmlSerializer = GetCachedSerializer(wrappingType);

            // Opt into sync IO support until we can work out an alternative https://github.com/aspnet/AspNetCore/issues/6397
            var syncIOFeature = context.HttpContext.Features.Get <Http.Features.IHttpBodyControlFeature>();

            if (syncIOFeature != null)
            {
                syncIOFeature.AllowSynchronousIO = true;
            }

            using (var textWriter = context.WriterFactory(context.HttpContext.Response.Body, writerSettings.Encoding))
            {
                using (var xmlWriter = CreateXmlWriter(context, textWriter, writerSettings))
                {
                    Serialize(xmlSerializer, xmlWriter, value);
                }

                // Perf: call FlushAsync to call WriteAsync on the stream with any content left in the TextWriter's
                // buffers. This is better than just letting dispose handle it (which would result in a synchronous
                // write).
                await textWriter.FlushAsync();
            }
        }
        /// <inheritdoc />
        public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (selectedEncoding == null)
            {
                throw new ArgumentNullException(nameof(selectedEncoding));
            }

            var response = context.HttpContext.Response;

            var responseStream = response.Body;
            FileBufferingWriteStream fileBufferingWriteStream = null;

            if (!_mvcOptions.SuppressOutputFormatterBuffering)
            {
                fileBufferingWriteStream = new FileBufferingWriteStream();
                responseStream           = fileBufferingWriteStream;
            }

            try
            {
                await using (var writer = context.WriterFactory(responseStream, selectedEncoding))
                {
                    using (var jsonWriter = CreateJsonWriter(writer))
                    {
                        var jsonSerializer = CreateJsonSerializer(context);
                        jsonSerializer.Serialize(jsonWriter, context.Object);
                    }
                }

                if (fileBufferingWriteStream != null)
                {
                    response.ContentLength = fileBufferingWriteStream.Length;
                    await fileBufferingWriteStream.DrainBufferAsync(response.Body);
                }
            }
            finally
            {
                if (fileBufferingWriteStream != null)
                {
                    await fileBufferingWriteStream.DisposeAsync();
                }
            }
        }
        /// <inheritdoc />
        public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (selectedEncoding == null)
            {
                throw new ArgumentNullException(nameof(selectedEncoding));
            }

            var response = context.HttpContext.Response;

            var writerSettings = WriterSettings.Clone();

            writerSettings.Encoding = selectedEncoding;

            // Wrap the object only if there is a wrapping type.
            var value        = context.Object;
            var wrappingType = GetSerializableType(context.ObjectType);

            if (wrappingType != null && wrappingType != context.ObjectType)
            {
                var wrapperProvider = WrapperProviderFactories.GetWrapperProvider(new WrapperProviderContext(
                                                                                      declaredType: context.ObjectType,
                                                                                      isSerialization: true));

                value = wrapperProvider.Wrap(value);
            }

            var xmlSerializer = GetCachedSerializer(wrappingType);

            using (var textWriter = context.WriterFactory(context.HttpContext.Response.Body, writerSettings.Encoding))
            {
                using (var xmlWriter = CreateXmlWriter(textWriter, writerSettings))
                {
                    xmlSerializer.Serialize(xmlWriter, value);
                }

                // Perf: call FlushAsync to call WriteAsync on the stream with any content left in the TextWriter's
                // buffers. This is better than just letting dispose handle it (which would result in a synchronous
                // write).
                await textWriter.FlushAsync();
            }
        }
        /// <inheritdoc />
        public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (selectedEncoding == null)
            {
                throw new ArgumentNullException(nameof(selectedEncoding));
            }

            // Opt into sync IO support until we can work out an alternative https://github.com/aspnet/AspNetCore/issues/6397
            var syncIOFeature = context.HttpContext.Features.Get <Http.Features.IHttpBodyControlFeature>();

            if (syncIOFeature != null)
            {
                syncIOFeature.AllowSynchronousIO = true;
            }

            var response = context.HttpContext.Response;

            using (var writer = context.WriterFactory(response.Body, selectedEncoding))
            {
                using (var jsonWriter = CreateJsonWriter(writer))
                {
                    var jsonSerializer = CreateJsonSerializer();
                    jsonSerializer.Serialize(jsonWriter, context.Object);
                }

                // Perf: call FlushAsync to call WriteAsync on the stream with any content left in the TextWriter's
                // buffers. This is better than just letting dispose handle it (which would result in a synchronous
                // write).
                await writer.FlushAsync();
            }
        }
Exemple #7
0
        /// <inheritdoc />
        public override async Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (selectedEncoding == null)
            {
                throw new ArgumentNullException(nameof(selectedEncoding));
            }

            var writerSettings = WriterSettings.Clone();

            writerSettings.Encoding = selectedEncoding;

            var httpContext = context.HttpContext;
            var response    = httpContext.Response;

            _mvcOptions ??= httpContext.RequestServices.GetRequiredService <IOptions <MvcOptions> >().Value;
            _asyncEnumerableReaderFactory ??= new AsyncEnumerableReader(_mvcOptions);

            var value     = context.Object;
            var valueType = context.ObjectType !;

            if (value is not null && _asyncEnumerableReaderFactory.TryGetReader(value.GetType(), out var reader))
            {
                Log.BufferingAsyncEnumerable(_logger, value);

                value = await reader(value);

                valueType = value.GetType();
            }

            // Wrap the object only if there is a wrapping type.
            var wrappingType = GetSerializableType(valueType);

            if (wrappingType != null && wrappingType != valueType)
            {
                var wrapperProvider = WrapperProviderFactories.GetWrapperProvider(new WrapperProviderContext(
                                                                                      declaredType: valueType,
                                                                                      isSerialization: true));

                Debug.Assert(wrapperProvider is not null);

                value = wrapperProvider.Wrap(value);
            }

            var xmlSerializer = GetCachedSerializer(wrappingType !);

            var responseStream = response.Body;
            FileBufferingWriteStream?fileBufferingWriteStream = null;

            if (!_mvcOptions.SuppressOutputFormatterBuffering)
            {
                fileBufferingWriteStream = new FileBufferingWriteStream();
                responseStream           = fileBufferingWriteStream;
            }

            try
            {
                await using (var textWriter = context.WriterFactory(responseStream, selectedEncoding))
                {
                    using var xmlWriter = CreateXmlWriter(context, textWriter, writerSettings);
                    Serialize(xmlSerializer, xmlWriter, value);
                }

                if (fileBufferingWriteStream != null)
                {
                    response.ContentLength = fileBufferingWriteStream.Length;
                    await fileBufferingWriteStream.DrainBufferAsync(response.BodyWriter);
                }
            }
            finally
            {
                if (fileBufferingWriteStream != null)
                {
                    await fileBufferingWriteStream.DisposeAsync();
                }
            }
        }