public override Task WriteResponseBodyAsync(OutputFormatterContext context)
        {
            if (context == null)
                throw new ArgumentNullException(nameof(context));

            var response = context.HttpContext.Response;
            var encoding = context.SelectedEncoding;

            StandardResponse standard;

            var o = context.Object as StandardResponse;
            if (o != null)
                standard = o;
            else
                standard = new StandardResponse
                {
                    Code = 200
                };
            return Task.Run(() =>
            {
                using (var stream = new HttpResponseStreamWriter(response.Body, encoding))
                {
                    WriteObject(stream, standard);
                }
            });
        }
Beispiel #2
0
        /// <summary>
        /// Asynchronously renders the specified <paramref name="view"/> to the response body.
        /// </summary>
        /// <param name="view">The <see cref="IView"/> to render.</param>
        /// <param name="actionContext">The <see cref="ActionContext"/> for the current executing action.</param>
        /// <param name="viewData">The <see cref="ViewDataDictionary"/> for the view being rendered.</param>
        /// <param name="tempData">The <see cref="ITempDataDictionary"/> for the view being rendered.</param>
        /// <returns>A <see cref="Task"/> that represents the asynchronous rendering.</returns>
        public static async Task ExecuteAsync([NotNull] IView view,
                                              [NotNull] ActionContext actionContext,
                                              [NotNull] ViewDataDictionary viewData,
                                              [NotNull] ITempDataDictionary tempData,
                                              [NotNull] HtmlHelperOptions htmlHelperOptions,
                                              MediaTypeHeaderValue contentType)
        {
            var response = actionContext.HttpContext.Response;

            contentType = contentType ?? DefaultContentType;
            if (contentType.Encoding == null)
            {
                // Do not modify the user supplied content type, so copy it instead
                contentType = contentType.Copy();
                contentType.Encoding = Encoding.UTF8;
            }

            response.ContentType = contentType.ToString();

            using (var writer = new HttpResponseStreamWriter(response.Body, contentType.Encoding))
            {
                var viewContext = new ViewContext(
                    actionContext,
                    view,
                    viewData,
                    tempData,
                    writer,
                    htmlHelperOptions);

                await view.RenderAsync(viewContext);
            }
        }
Beispiel #3
0
 public async Task ExecuteResultAsync(ActionContext context)
 {
     var response = context.HttpContext.Response;
     response.ContentType = ContentType;
     
     using (var writer = new HttpResponseStreamWriter(response.Body, Encoding.UTF8))
     {
         await _func(writer);
     }
 }
        public override Task WriteResponseBodyAsync(OutputFormatterContext context)
        {
            var response = context.HttpContext.Response;
            var selectedEncoding = context.SelectedEncoding;

            using (var writer = new HttpResponseStreamWriter(response.Body, selectedEncoding))
            {
                WriteObject(writer, context.Object);
            }

            return Task.FromResult(true);
        }
        public async Task DoesNotClose_UnderlyingStream_OnDisposingWriter()
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            await writer.WriteAsync("Hello");
            writer.Close();

            // Assert
            Assert.Equal(0, stream.CloseCallCount);
        }
Beispiel #6
0
        /// <summary>
        /// Asynchronously renders the specified <paramref name="view"/> to the response body.
        /// </summary>
        /// <param name="view">The <see cref="IView"/> to render.</param>
        /// <param name="actionContext">The <see cref="ActionContext"/> for the current executing action.</param>
        /// <param name="viewData">The <see cref="ViewDataDictionary"/> for the view being rendered.</param>
        /// <param name="tempData">The <see cref="ITempDataDictionary"/> for the view being rendered.</param>
        /// <returns>A <see cref="Task"/> that represents the asynchronous rendering.</returns>
        public static async Task ExecuteAsync([NotNull] IView view,
                                              [NotNull] ActionContext actionContext,
                                              [NotNull] ViewDataDictionary viewData,
                                              [NotNull] ITempDataDictionary tempData,
                                              [NotNull] HtmlHelperOptions htmlHelperOptions,
                                              MediaTypeHeaderValue contentType)
        {
            var response = actionContext.HttpContext.Response;

            var contentTypeHeader = contentType;
            Encoding encoding;
            if (contentTypeHeader == null)
            {
                contentTypeHeader = DefaultContentType;
                encoding = Encodings.UTF8EncodingWithoutBOM;
            }
            else
            {
                if (contentTypeHeader.Encoding == null)
                {
                    // 1. Do not modify the user supplied content type
                    // 2. Parse here to handle parameters apart from charset
                    contentTypeHeader = MediaTypeHeaderValue.Parse(contentTypeHeader.ToString());
                    contentTypeHeader.Encoding = Encodings.UTF8EncodingWithoutBOM;

                    encoding = Encodings.UTF8EncodingWithoutBOM;
                }
                else
                {
                    encoding = contentTypeHeader.Encoding;
                }
            }

            response.ContentType = contentTypeHeader.ToString();

            using (var writer = new HttpResponseStreamWriter(response.Body, encoding))
            {
                var viewContext = new ViewContext(
                    actionContext,
                    view,
                    viewData,
                    tempData,
                    writer,
                    htmlHelperOptions);

                await view.RenderAsync(viewContext);            }
        }
        public async Task DoesNotWriteBOM()
        {
            // Arrange
            var memoryStream = new MemoryStream();
            var encodingWithBOM = new UTF8Encoding(encoderShouldEmitUTF8Identifier: true);
            var writer = new HttpResponseStreamWriter(memoryStream, encodingWithBOM);
            var expectedData = new byte[] { 97, 98, 99, 100 }; // without BOM

            // Act
            using (writer)
            {
                await writer.WriteAsync("abcd");
            }

            // Assert
            Assert.Equal(expectedData, memoryStream.ToArray());
        }
        public async Task WriteCharAsync_WritesToStream(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            using (writer)
            {
                for (var i = 0; i < byteLength; i++)
                {
                    await writer.WriteAsync('a');
                }
            }

            // Assert
            Assert.Equal(byteLength, stream.Length);
        }
        public void FlushesBuffer_ButNotStream_OnFlush(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            writer.Write(new string('a', byteLength));

            var expectedWriteCount = Math.Ceiling((double)byteLength / HttpResponseStreamWriter.DefaultBufferSize);

            // Act
            writer.Flush();

            // Assert
            Assert.Equal(0, stream.FlushCallCount);
            Assert.Equal(expectedWriteCount, stream.WriteCallCount);
            Assert.Equal(byteLength, stream.Length);
        }
        public async Task FlushesBuffer_OnClose(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);
            await writer.WriteAsync(new string('a', byteLength));

            // Act
#if DNX451
            writer.Close();
#else
            writer.Dispose();
#endif

            // Assert
            Assert.Equal(0, stream.FlushCallCount);
            Assert.Equal(0, stream.FlushAsyncCallCount);
            Assert.Equal(byteLength, stream.Length);
        }
        public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context)
        {
            if (context == null)
                throw new ArgumentNullException(nameof(context));

            var response = context.HttpContext.Response;
            var encoding = context.ContentType?.Encoding ?? Encoding.UTF8;

            var o = context.Object as StandardResponse;
            var standard = o ?? StandardResponse.Create(context.Object);

            return Task.Run(() =>
            {
                using (var stream = new HttpResponseStreamWriter(response.Body, encoding))
                {
                    WriteObject(stream, standard);
                }
            });
        }
        public Task OnCustomRedirectToLogin(CookieRedirectContext context)
        {
            var actionContext = context.HttpContext.RequestServices.GetRequiredService<IActionContextAccessor>();
            if (actionContext.ActionContext == null)
                return _old(context);

            if (actionContext.ActionContext.ActionDescriptor.FilterDescriptors.Any(x => x.Filter is AjaxAttribute))
            {
                // this is an ajax request, return custom JSON telling user that they must be authenticated.
                var serializerSettings = context
                    .HttpContext
                    .RequestServices
                    .GetRequiredService<IOptions<MvcJsonOptions>>()
                    .Value
                    .SerializerSettings;

                context.Response.ContentType = "application/json";

                using (var writer = new HttpResponseStreamWriter(context.Response.Body, Encoding.UTF8))
                {
                    using (var jsonWriter = new JsonTextWriter(writer))
                    {
                        jsonWriter.CloseOutput = false;
                        var jsonSerializer = JsonSerializer.Create(serializerSettings);
                        jsonSerializer.Serialize(jsonWriter, new
                        {
                            success = false,
                            error = "You must be signed in."
                        });
                    }
                }

                return Task.FromResult(0);
            }
            else
            {
                // this is a normal request to an endpoint that is secured.
                // do what ASP.NET used to do.
                return _old(context);
            }
        }
        public async Task WritesData_OfDifferentLength_InExpectedEncoding(
            char character,
            int charCount,
            string encodingName)
        {
            // Arrange
            var    encoding      = Encoding.GetEncoding(encodingName);
            string data          = new string(character, charCount);
            var    expectedBytes = encoding.GetBytes(data);
            var    stream        = new MemoryStream();
            var    writer        = new HttpResponseStreamWriter(stream, encoding);

            // Act
            using (writer)
            {
                await writer.WriteAsync(data);
            }

            // Assert
            Assert.Equal(expectedBytes, stream.ToArray());
        }
        public void HttpResponseStreamWriter_UsingPooledBuffers()
        {
            // Arrange
            var encoding = Encoding.UTF8;
            var stream   = new MemoryStream();

            var expectedBytes = encoding.GetBytes("Hello, World!");

            using (var writer = new HttpResponseStreamWriter(
                       stream,
                       encoding,
                       1024,
                       ArrayPool <byte> .Shared,
                       ArrayPool <char> .Shared))
            {
                // Act
                writer.Write("Hello, World!");
            }

            // Assert
            Assert.Equal(expectedBytes, stream.ToArray());
        }
        public async Task WritesData_InExpectedEncoding(string data, string encodingName)
        {
            // Arrange
            var encoding = Encoding.GetEncoding(encodingName);
            var expectedBytes = encoding.GetBytes(data);
            var stream = new MemoryStream();
            var writer = new HttpResponseStreamWriter(stream, encoding);

            // Act
            using (writer)
            {
                await writer.WriteAsync(data);
            }

            // Assert
            Assert.Equal(expectedBytes, stream.ToArray());
        }
        public void HttpResponseStreamWriter_UsingPooledBuffers_SmallByteBuffer()
        {
            // Arrange
            var encoding = Encoding.UTF8;
            var stream = new MemoryStream();

            var message =
                "The byte buffer must have a length of at least '12291' to be used with a char buffer of " +
                "size '4096' and encoding 'Unicode (UTF-8)'. Use 'System.Text.Encoding.GetMaxByteCount' " +
                "to compute the correct size for the byte buffer.";

            using (var bytePool = new DefaultArraySegmentPool<byte>())
            {
                using (var charPool = new DefaultArraySegmentPool<char>())
                {
                    LeasedArraySegment<byte> bytes = null;
                    LeasedArraySegment<char> chars = null;
                    HttpResponseStreamWriter writer = null;

                    try
                    {
                        bytes = bytePool.Lease(1024);
                        chars = charPool.Lease(4096);

                        // Act & Assert
                        ExceptionAssert.ThrowsArgument(
                            () => writer = new HttpResponseStreamWriter(stream, encoding, chars.Data.Count, bytes, chars),
                            "byteBuffer",
                            message);
                        writer.Dispose();
                    }
                    catch
                    {
                        if (bytes != null)
                        {
                            bytes.Owner.Return(bytes);
                        }

                        if (chars != null)
                        {
                            chars.Owner.Return(chars);
                        }
                    }
                }
            }
        }
        public async Task FlushesBuffer_OnDispose(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);
            await writer.WriteAsync(new string('a', byteLength));

            // Act
            writer.Dispose();

            // Assert
            Assert.Equal(0, stream.FlushCallCount);
            Assert.Equal(0, stream.FlushAsyncCallCount);
            Assert.Equal(byteLength, stream.Length);
        }
Beispiel #18
0
        /// <inheritdoc />
        public override Task ExecuteResultAsync(ActionContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var loggerFactory = context.HttpContext.RequestServices.GetRequiredService <ILoggerFactory>();
            var logger        = loggerFactory.CreateLogger <JsonResult>();

            var response = context.HttpContext.Response;

            var contentTypeHeader = ContentType;

            if (contentTypeHeader == null)
            {
                contentTypeHeader = DefaultContentType;
            }
            else
            {
                if (contentTypeHeader.Encoding == null)
                {
                    // Do not modify the user supplied content type, so copy it instead
                    contentTypeHeader          = contentTypeHeader.Copy();
                    contentTypeHeader.Encoding = Encoding.UTF8;
                }
            }

            response.ContentType = contentTypeHeader.ToString();

            if (StatusCode != null)
            {
                response.StatusCode = StatusCode.Value;
            }

            var serializerSettings = _serializerSettings;

            if (serializerSettings == null)
            {
                serializerSettings = context
                                     .HttpContext
                                     .RequestServices
                                     .GetRequiredService <IOptions <MvcJsonOptions> >()
                                     .Value
                                     .SerializerSettings;
            }

            logger.JsonResultExecuting(Value);

            using (var writer = new HttpResponseStreamWriter(response.Body, contentTypeHeader.Encoding))
            {
                using (var jsonWriter = new JsonTextWriter(writer))
                {
                    jsonWriter.CloseOutput = false;
                    var jsonSerializer = JsonSerializer.Create(serializerSettings);
                    jsonSerializer.Serialize(jsonWriter, Value);
                }
            }

            return(Task.FromResult(true));
        }
Beispiel #19
0
        /// <inheritdoc />
        public override Task ExecuteResultAsync(ActionContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var response = context.HttpContext.Response;

            var contentTypeHeader = ContentType;
            if (contentTypeHeader == null)
            {
                contentTypeHeader = DefaultContentType;
            }
            else
            {
                if (contentTypeHeader.Encoding == null)
                {
                    // Do not modify the user supplied content type, so copy it instead
                    contentTypeHeader = contentTypeHeader.Copy();
                    contentTypeHeader.Encoding = Encoding.UTF8;
                }
            }

            response.ContentType = contentTypeHeader.ToString();

            if (StatusCode != null)
            {
                response.StatusCode = StatusCode.Value;
            }

            var serializerSettings = _serializerSettings;
            if (serializerSettings == null)
            {
                serializerSettings = context
                    .HttpContext
                    .RequestServices
                    .GetRequiredService<IOptions<MvcJsonOptions>>()
                    .Value
                    .SerializerSettings;
            }

            using (var writer = new HttpResponseStreamWriter(response.Body, contentTypeHeader.Encoding))
            {
                using (var jsonWriter = new JsonTextWriter(writer))
                {
                    jsonWriter.CloseOutput = false;
                    var jsonSerializer = JsonSerializer.Create(serializerSettings);
                    jsonSerializer.Serialize(jsonWriter, Value);
                }
            }

            return Task.FromResult(true);
        }
        /// <inheritdoc />
        public override async Task ExecuteResultAsync(ActionContext context)
        {
            var response = context.HttpContext.Response;
            var services = context.HttpContext.RequestServices;

            var htmlHelperOptions   = services.GetRequiredService <IOptions <MvcViewOptions> >().Value.HtmlHelperOptions;
            var viewComponentHelper = services.GetRequiredService <IViewComponentHelper>();

            var viewData = ViewData;

            if (viewData == null)
            {
                var modelMetadataProvider = services.GetRequiredService <IModelMetadataProvider>();
                viewData = new ViewDataDictionary(modelMetadataProvider, context.ModelState);
            }

            var contentType = ContentType;

            if (contentType != null && contentType.Encoding == null)
            {
                // Do not modify the user supplied content type, so copy it instead
                contentType          = contentType.Copy();
                contentType.Encoding = Encoding.UTF8;
            }

            // Priority list for setting content-type/encoding:
            //      1. this.ContentType (set by the user on the result)
            //      2. response.ContentType (likely set by the user in controller code)
            //      3. ViewExecutor.DefaultContentType (sensible default)
            //
            //
            response.ContentType =
                contentType?.ToString() ??
                response.ContentType ??
                ViewExecutor.DefaultContentType.ToString();

            if (StatusCode != null)
            {
                response.StatusCode = StatusCode.Value;
            }

            var encoding = contentType?.Encoding ?? ViewExecutor.DefaultContentType?.Encoding;

            using (var writer = new HttpResponseStreamWriter(response.Body, encoding))
            {
                var viewContext = new ViewContext(
                    context,
                    NullView.Instance,
                    viewData,
                    TempData,
                    writer,
                    htmlHelperOptions);

                (viewComponentHelper as ICanHasViewContext)?.Contextualize(viewContext);

                if (ViewComponentType == null && ViewComponentName == null)
                {
                    throw new InvalidOperationException(Resources.FormatViewComponentResult_NameOrTypeMustBeSet(
                                                            nameof(ViewComponentName),
                                                            nameof(ViewComponentType)));
                }
                else if (ViewComponentType == null)
                {
                    await viewComponentHelper.RenderInvokeAsync(ViewComponentName, Arguments);
                }
                else
                {
                    await viewComponentHelper.RenderInvokeAsync(ViewComponentType, Arguments);
                }
            }
        }
Beispiel #21
0
        /// <inheritdoc />
        public override async Task ExecuteResultAsync(ActionContext context)
        {
            var response = context.HttpContext.Response;
            var services = context.HttpContext.RequestServices;

            var htmlHelperOptions = services.GetRequiredService<IOptions<MvcViewOptions>>().Value.HtmlHelperOptions;
            var viewComponentHelper = services.GetRequiredService<IViewComponentHelper>();

            var loggerFactory = services.GetRequiredService<ILoggerFactory>();
            var logger = loggerFactory.CreateLogger<ViewComponentResult>();

            var viewData = ViewData;
            if (viewData == null)
            {
                var modelMetadataProvider = services.GetRequiredService<IModelMetadataProvider>();
                viewData = new ViewDataDictionary(modelMetadataProvider, context.ModelState);
            }

            var tempData = TempData;
            if (tempData == null)
            {
                tempData = services.GetRequiredService<ITempDataDictionary>();
            }

            var contentType = ContentType;
            if (contentType != null && contentType.Encoding == null)
            {
                // Do not modify the user supplied content type, so copy it instead
                contentType = contentType.Copy();
                contentType.Encoding = Encoding.UTF8;
            }

            // Priority list for setting content-type/encoding:
            //      1. this.ContentType (set by the user on the result)
            //      2. response.ContentType (likely set by the user in controller code)
            //      3. ViewExecutor.DefaultContentType (sensible default)
            //
            //
            response.ContentType =
                contentType?.ToString() ??
                response.ContentType ??
                ViewExecutor.DefaultContentType.ToString();

            if (StatusCode != null)
            {
                response.StatusCode = StatusCode.Value;
            }

            var encoding = contentType?.Encoding ?? ViewExecutor.DefaultContentType?.Encoding;
            using (var writer = new HttpResponseStreamWriter(response.Body, encoding))
            {
                var viewContext = new ViewContext(
                    context,
                    NullView.Instance,
                    viewData,
                    tempData,
                    writer,
                    htmlHelperOptions);

                (viewComponentHelper as ICanHasViewContext)?.Contextualize(viewContext);

                if (ViewComponentType == null && ViewComponentName == null)
                {
                    throw new InvalidOperationException(Resources.FormatViewComponentResult_NameOrTypeMustBeSet(
                        nameof(ViewComponentName),
                        nameof(ViewComponentType)));
                }
                else if (ViewComponentType == null)
                {
                    logger.ViewComponentResultExecuting(ViewComponentName, Arguments);
                    await viewComponentHelper.RenderInvokeAsync(ViewComponentName, Arguments);
                }
                else
                {
                    logger.ViewComponentResultExecuting(ViewComponentType, Arguments);
                    await viewComponentHelper.RenderInvokeAsync(ViewComponentType, Arguments);
                }
            }
        }
        /// <inheritdoc />
        public override async Task ExecuteResultAsync(ActionContext context)
        {
            var response = context.HttpContext.Response;
            var services = context.HttpContext.RequestServices;

            var htmlHelperOptions   = services.GetRequiredService <IOptions <MvcViewOptions> >().Value.HtmlHelperOptions;
            var viewComponentHelper = services.GetRequiredService <IViewComponentHelper>();

            var loggerFactory = services.GetRequiredService <ILoggerFactory>();
            var logger        = loggerFactory.CreateLogger <ViewComponentResult>();
            var htmlEncoder   = services.GetRequiredService <HtmlEncoder>();

            var viewData = ViewData;

            if (viewData == null)
            {
                var modelMetadataProvider = services.GetRequiredService <IModelMetadataProvider>();
                viewData = new ViewDataDictionary(modelMetadataProvider, context.ModelState);
            }

            var tempData = TempData;

            if (tempData == null)
            {
                var factory = services.GetRequiredService <ITempDataDictionaryFactory>();
                tempData = factory.GetTempData(context.HttpContext);
            }

            string   resolvedContentType         = null;
            Encoding resolvedContentTypeEncoding = null;

            ResponseContentTypeHelper.ResolveContentTypeAndEncoding(
                ContentType,
                response.ContentType,
                ViewExecutor.DefaultContentType,
                out resolvedContentType,
                out resolvedContentTypeEncoding);

            response.ContentType = resolvedContentType;

            if (StatusCode != null)
            {
                response.StatusCode = StatusCode.Value;
            }

            using (var writer = new HttpResponseStreamWriter(response.Body, resolvedContentTypeEncoding))
            {
                var viewContext = new ViewContext(
                    context,
                    NullView.Instance,
                    viewData,
                    tempData,
                    writer,
                    htmlHelperOptions);

                (viewComponentHelper as ICanHasViewContext)?.Contextualize(viewContext);
                var result = await GetViewComponentResult(viewComponentHelper, logger);

                result.WriteTo(writer, htmlEncoder);
            }
        }
        public async Task WriteCharAsync_WritesToStream(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            using (writer)
            {
                for (var i = 0; i < byteLength; i++)
                {
                    await writer.WriteAsync('a');
                }
            }

            // Assert
            Assert.Equal(byteLength, stream.Length);
        }
        public async Task NoDataWritten_FlushAsync_DoesNotFlushUnderlyingStream()
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            await writer.FlushAsync();

            // Assert
            Assert.Equal(0, stream.FlushAsyncCallCount);
            Assert.Equal(0, stream.Length);
        }
        public async Task FlushesBuffer_ButNotStream_OnFlushAsync(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);
            await writer.WriteAsync(new string('a', byteLength));

            var expectedWriteCount = Math.Ceiling((double)byteLength / HttpResponseStreamWriter.DefaultBufferSize);

            // Act
            await writer.FlushAsync();

            // Assert
            Assert.Equal(0, stream.FlushAsyncCallCount);
            Assert.Equal(expectedWriteCount, stream.WriteAsyncCallCount);
            Assert.Equal(byteLength, stream.Length);
        }
        public void HttpResponseStreamWriter_UsingPooledBuffers()
        {
            // Arrange
            var encoding = Encoding.UTF8;
            var stream = new MemoryStream();

            var expectedBytes = encoding.GetBytes("Hello, World!");

            using (var writer = new HttpResponseStreamWriter(
                stream,
                encoding,
                1024,
                ArrayPool<byte>.Shared,
                ArrayPool<char>.Shared))
            {
                // Act
                writer.Write("Hello, World!");
            }

            // Assert
            Assert.Equal(expectedBytes, stream.ToArray());
        }
        public async Task WriteCharArrayAsync_WritesToStream(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);

            // Act
            using (writer)
            {
                await writer.WriteAsync((new string('a', byteLength)).ToCharArray());
            }

            // Assert
            Assert.Equal(byteLength, stream.Length);
        }
        public void HttpResponseStreamWriter_UsingPooledBuffers()
        {
            // Arrange
            var encoding = Encoding.UTF8;
            var stream = new MemoryStream();

            var expectedBytes = encoding.GetBytes("Hello, World!");

            using (var bytePool = new DefaultArraySegmentPool<byte>())
            {
                using (var charPool = new DefaultArraySegmentPool<char>())
                {
                    LeasedArraySegment<byte> bytes = null;
                    LeasedArraySegment<char> chars = null;
                    HttpResponseStreamWriter writer;

                    try
                    {
                        bytes = bytePool.Lease(4096);
                        chars = charPool.Lease(1024);

                        writer = new HttpResponseStreamWriter(stream, encoding, 1024, bytes, chars);
                    }
                    catch
                    {
                        if (bytes != null)
                        {
                            bytes.Owner.Return(bytes);
                        }

                        if (chars != null)
                        {
                            chars.Owner.Return(chars);
                        }

                        throw;
                    }

                    // Act
                    using (writer)
                    {
                        writer.Write("Hello, World!");
                    }
                }
            }

            // Assert
            Assert.Equal(expectedBytes, stream.ToArray());
        }
        public async Task WritesData_OfDifferentLength_InExpectedEncoding(
            char character,
            int charCount,
            string encodingName)
        {
            // Arrange
            var encoding = Encoding.GetEncoding(encodingName);
            string data = new string(character, charCount);
            var expectedBytes = encoding.GetBytes(data);
            var stream = new MemoryStream();
            var writer = new HttpResponseStreamWriter(stream, encoding);

            // Act
            using (writer)
            {
                await writer.WriteAsync(data);
            }

            // Assert
            Assert.Equal(expectedBytes, stream.ToArray());
        }
        /// <inheritdoc />
        public override async Task ExecuteResultAsync(ActionContext context)
        {
            var response = context.HttpContext.Response;
            var services = context.HttpContext.RequestServices;

            var htmlHelperOptions = services.GetRequiredService<IOptions<MvcViewOptions>>().Options.HtmlHelperOptions;
            var viewComponentHelper = services.GetRequiredService<IViewComponentHelper>();

            var viewData = ViewData;
            if (viewData == null)
            {
                var modelMetadataProvider = services.GetRequiredService<IModelMetadataProvider>();
                viewData = new ViewDataDictionary(modelMetadataProvider, context.ModelState);
            }

            var contentType = ContentType ?? ViewExecutor.DefaultContentType;
            if (contentType.Encoding == null)
            {
                // Do not modify the user supplied content type, so copy it instead
                contentType = contentType.Copy();
                contentType.Encoding = Encoding.UTF8;
            }

            if (StatusCode != null)
            {
                response.StatusCode = StatusCode.Value;
            }

            response.ContentType = contentType.ToString();

            using (var writer = new HttpResponseStreamWriter(response.Body, contentType.Encoding))
            {
                var viewContext = new ViewContext(
                    context,
                    NullView.Instance,
                    viewData,
                    TempData,
                    writer,
                    htmlHelperOptions);

                (viewComponentHelper as ICanHasViewContext)?.Contextualize(viewContext);

                if (ViewComponentType == null && ViewComponentName == null)
                {
                    throw new InvalidOperationException(Resources.FormatViewComponentResult_NameOrTypeMustBeSet(
                        nameof(ViewComponentName),
                        nameof(ViewComponentType)));
                }
                else if (ViewComponentType == null)
                {
                    await viewComponentHelper.RenderInvokeAsync(ViewComponentName, Arguments);
                }
                else
                {
                    await viewComponentHelper.RenderInvokeAsync(ViewComponentType, Arguments);
                }
            }
        }
        public void FlushesBuffer_OnFlush(int byteLength)
        {
            // Arrange
            var stream = new TestMemoryStream();
            var writer = new HttpResponseStreamWriter(stream, Encoding.UTF8);
            writer.Write(new string('a', byteLength));

            // Act
            writer.Flush();

            // Assert
            Assert.Equal(1, stream.FlushCallCount);
            Assert.Equal(byteLength, stream.Length);
        }
        /// <inheritdoc />
        public override async Task ExecuteResultAsync(ActionContext context)
        {
            var response = context.HttpContext.Response;
            var services = context.HttpContext.RequestServices;

            var htmlHelperOptions = services.GetRequiredService<IOptions<MvcViewOptions>>().Value.HtmlHelperOptions;
            var viewComponentHelper = services.GetRequiredService<IViewComponentHelper>();

            var loggerFactory = services.GetRequiredService<ILoggerFactory>();
            var logger = loggerFactory.CreateLogger<ViewComponentResult>();
            var htmlEncoder = services.GetRequiredService<HtmlEncoder>();

            var viewData = ViewData;
            if (viewData == null)
            {
                var modelMetadataProvider = services.GetRequiredService<IModelMetadataProvider>();
                viewData = new ViewDataDictionary(modelMetadataProvider, context.ModelState);
            }

            var tempData = TempData;
            if (tempData == null)
            {
                var factory = services.GetRequiredService<ITempDataDictionaryFactory>();
                tempData = factory.GetTempData(context.HttpContext);
            }

            string resolvedContentType = null;
            Encoding resolvedContentTypeEncoding = null;
            ResponseContentTypeHelper.ResolveContentTypeAndEncoding(
                ContentType,
                response.ContentType,
                ViewExecutor.DefaultContentType,
                out resolvedContentType,
                out resolvedContentTypeEncoding);

            response.ContentType = resolvedContentType;

            if (StatusCode != null)
            {
                response.StatusCode = StatusCode.Value;
            }

            using (var writer = new HttpResponseStreamWriter(response.Body, resolvedContentTypeEncoding))
            {
                var viewContext = new ViewContext(
                    context,
                    NullView.Instance,
                    viewData,
                    tempData,
                    writer,
                    htmlHelperOptions);

                (viewComponentHelper as ICanHasViewContext)?.Contextualize(viewContext);
                var result = await GetViewComponentResult(viewComponentHelper, logger);

                result.WriteTo(writer, htmlEncoder);
            }
        }