Use FileBufferingWriteStream in ViewComponentResultExecutor (#9523)

Fixes https://github.com/aspnet/AspNetCore/issues/9443
This commit is contained in:
Pranav K 2019-04-18 19:27:55 -07:00 committed by GitHub
parent 9e4d5c14c7
commit acf45106fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 4 deletions

View File

@ -12,6 +12,7 @@ using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Buffers;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Filters;
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
@ -148,14 +149,13 @@ namespace Microsoft.AspNetCore.Mvc.ViewFeatures
}
else
{
using var memoryStream = new MemoryStream();
using (var intermediateWriter = _writerFactory.CreateWriter(response.Body, resolvedContentTypeEncoding))
using var bufferingStream = new FileBufferingWriteStream();
using (var intermediateWriter = _writerFactory.CreateWriter(bufferingStream, resolvedContentTypeEncoding))
{
viewComponentResult.WriteTo(intermediateWriter, _htmlEncoder);
}
memoryStream.Position = 0;
await memoryStream.CopyToAsync(response.Body);
await bufferingStream.DrainBufferAsync(response.Body);
}
}
}

View File

@ -439,6 +439,48 @@ namespace Microsoft.AspNetCore.Mvc
Assert.Equal(expected, body);
}
[Fact]
public async Task ExecuteResultAsync_WithCustomViewComponentHelper_ForLargeText()
{
// Arrange
var expected = new string('a', 64 * 1024 * 1024);
var methodInfo = typeof(TextViewComponent).GetMethod(nameof(TextViewComponent.Invoke));
var descriptor = new ViewComponentDescriptor()
{
FullName = "Full.Name.Text",
ShortName = "Text",
TypeInfo = typeof(TextViewComponent).GetTypeInfo(),
MethodInfo = methodInfo,
Parameters = methodInfo.GetParameters(),
};
var result = Task.FromResult<IHtmlContent>(new HtmlContentBuilder().AppendHtml(expected));
var helper = Mock.Of<IViewComponentHelper>(h => h.InvokeAsync(It.IsAny<Type>(), It.IsAny<object>()) == result);
var httpContext = new DefaultHttpContext();
var services = CreateServices(diagnosticListener: null, httpContext, new[] { descriptor });
services.AddSingleton<IViewComponentHelper>(helper);
httpContext.RequestServices = services.BuildServiceProvider();
httpContext.Response.Body = new MemoryStream();
var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor());
var viewComponentResult = new ViewComponentResult()
{
Arguments = new { name = "World!" },
ViewComponentType = typeof(TextViewComponent),
TempData = _tempDataDictionary,
};
// Act
await viewComponentResult.ExecuteResultAsync(actionContext);
// Assert
var body = ReadBody(actionContext.HttpContext.Response);
Assert.Equal(expected, body);
}
[Fact]
public async Task ExecuteResultAsync_SetsStatusCode()
{