/// <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(); } }
/// <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(); } }
/// <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(); } } }