Exemple #1
0
        /// <summary>
        /// Gets the type to which the XML will be deserialized.
        /// </summary>
        /// <param name="declaredType">The declared type.</param>
        /// <returns>The type to which the XML will be deserialized.</returns>
        protected virtual Type GetSerializableType([NotNull] Type declaredType)
        {
            var wrapperProvider = WrapperProviderFactories.GetWrapperProvider(
                new WrapperProviderContext(declaredType, isSerialization: false));

            return(wrapperProvider?.WrappingType ?? declaredType);
        }
        /// <inheritdoc />
        public override Task WriteResponseBodyAsync([NotNull] OutputFormatterContext context)
        {
            var tempWriterSettings = WriterSettings.Clone();

            tempWriterSettings.Encoding = context.SelectedEncoding;

            using (var xmlWriter = CreateXmlWriter(context.HttpContext.Response.Body, tempWriterSettings))
            {
                var obj         = context.Object;
                var runtimeType = obj?.GetType();

                var resolvedType = ResolveType(context.DeclaredType, runtimeType);

                var wrappingType = GetSerializableType(resolvedType);

                // Wrap the object only if there is a wrapping type.
                if (wrappingType != null && wrappingType != resolvedType)
                {
                    var wrapperProvider = WrapperProviderFactories.GetWrapperProvider(
                        new WrapperProviderContext(
                            declaredType: resolvedType,
                            isSerialization: true));

                    obj = wrapperProvider.Wrap(obj);
                }

                var dataContractSerializer = GetCachedSerializer(wrappingType);
                dataContractSerializer.WriteObject(xmlWriter, obj);
            }

            return(Task.FromResult(true));
        }
        /// <summary>
        /// Gets the type to be serialized.
        /// </summary>
        /// <param name="type">The original type to be serialized</param>
        /// <returns>The original or wrapped type provided by any <see cref="IWrapperProvider"/>s.</returns>
        protected virtual Type GetSerializableType(Type type)
        {
            var wrapperProvider = WrapperProviderFactories.GetWrapperProvider(
                new WrapperProviderContext(type, isSerialization: true));

            return(wrapperProvider?.WrappingType ?? type);
        }
        /// <summary>
        /// Gets the type to which the XML will be deserialized.
        /// </summary>
        /// <param name="declaredType">The declared type.</param>
        /// <returns>The type to which the XML will be deserialized.</returns>
        protected virtual Type GetSerializableType(Type declaredType)
        {
            if (declaredType == null)
            {
                throw new ArgumentNullException(nameof(declaredType));
            }

            var wrapperProvider = WrapperProviderFactories.GetWrapperProvider(
                new WrapperProviderContext(declaredType, isSerialization: false));

            return(wrapperProvider?.WrappingType ?? declaredType);
        }
        /// <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 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();
            }
        }
Exemple #7
0
        /// <summary>
        /// Initializes a new instance of <see cref="XmlSerializerOutputFormatter"/>
        /// </summary>
        /// <param name="writerSettings">The settings to be used by the <see cref="XmlSerializer"/>.</param>
        /// <param name="loggerFactory">The <see cref="ILoggerFactory"/>.</param>
        public XmlSerializerOutputFormatter(XmlWriterSettings writerSettings, ILoggerFactory loggerFactory)
        {
            if (writerSettings == null)
            {
                throw new ArgumentNullException(nameof(writerSettings));
            }

            SupportedEncodings.Add(Encoding.UTF8);
            SupportedEncodings.Add(Encoding.Unicode);

            SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationXml);
            SupportedMediaTypes.Add(MediaTypeHeaderValues.TextXml);
            SupportedMediaTypes.Add(MediaTypeHeaderValues.ApplicationAnyXmlSyntax);

            WriterSettings = writerSettings;

            WrapperProviderFactories = WrapperProviderFactoriesExtensions.GetDefaultProviderFactories();
            WrapperProviderFactories.Add(new EnumerableWrapperProviderFactory(WrapperProviderFactories));

            _logger = loggerFactory?.CreateLogger(GetType());
        }
        /// <inheritdoc />
        public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var response = context.HttpContext.Response;

            var writerSettings = WriterSettings.Clone();

            writerSettings.Encoding = context.ContentType.Encoding ?? Encoding.UTF8;

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

            return(TaskCache.CompletedTask);
        }
Exemple #9
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();
                }
            }
        }