Write our ViewBuffer values asynchronously
This commit is contained in:
parent
57bf12311b
commit
2eb6cd655b
|
|
@ -8,6 +8,7 @@ using System.Text.Encodings.Web;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Html;
|
||||
using Microsoft.AspNet.Mvc.ViewFeatures;
|
||||
using Microsoft.AspNet.Mvc.ViewFeatures.Buffer;
|
||||
|
||||
namespace Microsoft.AspNet.Mvc.Razor
|
||||
{
|
||||
|
|
@ -24,11 +25,12 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
/// </summary>
|
||||
/// <param name="unbufferedWriter">The <see cref="TextWriter"/> to write output to when this instance
|
||||
/// is no longer buffering.</param>
|
||||
/// <param name="buffer">The <see cref="IHtmlContentBuilder"/> to buffer output to.</param>
|
||||
/// <param name="buffer">The <see cref="ViewBuffer"/> to buffer output to.</param>
|
||||
/// <param name="encoder">The HTML encoder.</param>
|
||||
public RazorTextWriter(TextWriter unbufferedWriter, IHtmlContentBuilder buffer, HtmlEncoder encoder)
|
||||
public RazorTextWriter(TextWriter unbufferedWriter, ViewBuffer buffer, HtmlEncoder encoder)
|
||||
{
|
||||
UnbufferedWriter = unbufferedWriter;
|
||||
Buffer = buffer;
|
||||
HtmlEncoder = encoder;
|
||||
|
||||
BufferedWriter = new HtmlContentWrapperTextWriter(buffer, unbufferedWriter.Encoding);
|
||||
|
|
@ -47,7 +49,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
/// <summary>
|
||||
/// Gets the buffered content.
|
||||
/// </summary>
|
||||
public IHtmlContent Buffer => BufferedWriter.ContentBuilder;
|
||||
public ViewBuffer Buffer { get; }
|
||||
|
||||
// Internal for unit testing
|
||||
internal HtmlContentWrapperTextWriter BufferedWriter { get; }
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ namespace Microsoft.AspNet.Mvc.Razor
|
|||
if (bodyWriter.IsBuffering)
|
||||
{
|
||||
// Only copy buffered content to the Output if we're currently buffering.
|
||||
bodyWriter.Buffer.WriteTo(context.Writer, _htmlEncoder);
|
||||
await bodyWriter.Buffer.WriteToAsync(context.Writer, _htmlEncoder);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Html;
|
||||
using Microsoft.AspNet.Mvc.Rendering;
|
||||
|
||||
|
|
@ -142,7 +143,73 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures.Buffer
|
|||
for (var j = 0; j < count; j++)
|
||||
{
|
||||
var value = segment[j];
|
||||
value.WriteTo(writer, encoder);
|
||||
|
||||
var valueAsString = value.Value as string;
|
||||
if (valueAsString != null)
|
||||
{
|
||||
writer.Write(valueAsString);
|
||||
continue;
|
||||
}
|
||||
|
||||
var valueAsHtmlContent = value.Value as IHtmlContent;
|
||||
if (valueAsHtmlContent != null)
|
||||
{
|
||||
valueAsHtmlContent.WriteTo(writer, encoder);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the buffered content to <paramref name="writer"/>.
|
||||
/// </summary>
|
||||
/// <param name="writer">The <see cref="TextWriter"/>.</param>
|
||||
/// <param name="encoder">The <see cref="HtmlEncoder"/>.</param>
|
||||
/// <returns>A <see cref="Task"/> which will complete once content has been written.</returns>
|
||||
public async Task WriteToAsync(TextWriter writer, HtmlEncoder encoder)
|
||||
{
|
||||
if (BufferSegments == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var htmlTextWriter = writer as HtmlTextWriter;
|
||||
if (htmlTextWriter != null)
|
||||
{
|
||||
htmlTextWriter.Write(this);
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < BufferSegments.Count; i++)
|
||||
{
|
||||
var segment = BufferSegments[i];
|
||||
var count = i == BufferSegments.Count - 1 ? CurrentCount : segment.Length;
|
||||
|
||||
for (var j = 0; j < count; j++)
|
||||
{
|
||||
var value = segment[j];
|
||||
|
||||
var valueAsString = value.Value as string;
|
||||
if (valueAsString != null)
|
||||
{
|
||||
await writer.WriteAsync(valueAsString);
|
||||
continue;
|
||||
}
|
||||
|
||||
var valueAsViewBuffer = value.Value as ViewBuffer;
|
||||
if (valueAsViewBuffer != null)
|
||||
{
|
||||
await valueAsViewBuffer.WriteToAsync(writer, encoder);
|
||||
continue;
|
||||
}
|
||||
|
||||
var valueAsHtmlContent = value.Value as IHtmlContent;
|
||||
if (valueAsHtmlContent != null)
|
||||
{
|
||||
valueAsHtmlContent.WriteTo(writer, encoder);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,31 +35,5 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures.Buffer
|
|||
/// Gets the value.
|
||||
/// </summary>
|
||||
public object Value { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Writes the <see cref="Value"/> by encoding it with the specified <paramref name="encoder"/> to the
|
||||
/// specified <paramref name="writer"/>.
|
||||
/// </summary>
|
||||
/// <param name="writer">The <see cref="TextWriter"/> to write the value to.</param>
|
||||
/// <param name="encoder">The <see cref="HtmlEncoder"/> which encodes the content to be written.</param>
|
||||
public void WriteTo(TextWriter writer, HtmlEncoder encoder)
|
||||
{
|
||||
if (Value == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var stringValue = Value as string;
|
||||
if (stringValue != null)
|
||||
{
|
||||
writer.Write(stringValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Assert(Value is IHtmlContent);
|
||||
var htmlContentValue = (IHtmlContent)Value;
|
||||
htmlContentValue.WriteTo(writer, encoder);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Html;
|
||||
using Microsoft.AspNet.Mvc.Rendering;
|
||||
using Microsoft.AspNet.Mvc.ViewFeatures.Buffer;
|
||||
|
|
@ -166,5 +167,63 @@ namespace Microsoft.AspNet.Mvc.Razor.Buffer
|
|||
// Assert
|
||||
Assert.Equal(expected, writer.ToString());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WriteToAsync_WritesSelf_WhenWriterIsHtmlTextWriter()
|
||||
{
|
||||
// Arrange
|
||||
var buffer = new ViewBuffer(new TestViewBufferScope(), "some-name");
|
||||
var htmlWriter = new Mock<HtmlTextWriter>();
|
||||
htmlWriter.Setup(w => w.Write(buffer)).Verifiable();
|
||||
|
||||
// Act
|
||||
buffer.Append("Hello world");
|
||||
await buffer.WriteToAsync(htmlWriter.Object, new HtmlTestEncoder());
|
||||
|
||||
// Assert
|
||||
htmlWriter.Verify();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task WriteToAsync_WritesRazorValues_ToTextWriter()
|
||||
{
|
||||
// Arrange
|
||||
var buffer = new ViewBuffer(new TestViewBufferScope(), "some-name");
|
||||
var writer = new StringWriter();
|
||||
|
||||
// Act
|
||||
buffer.Append("Hello");
|
||||
buffer.AppendHtml(new HtmlString(" world"));
|
||||
buffer.AppendHtml(" 123");
|
||||
|
||||
await buffer.WriteToAsync(writer, new HtmlTestEncoder());
|
||||
|
||||
// Assert
|
||||
Assert.Equal("Hello world 123", writer.ToString());
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(9)]
|
||||
[InlineData(10)]
|
||||
[InlineData(11)]
|
||||
[InlineData(23)]
|
||||
public async Task WriteToAsync_WritesRazorValuesFromAllBuffers(int valuesToWrite)
|
||||
{
|
||||
// Arrange
|
||||
var buffer = new ViewBuffer(new TestViewBufferScope(4), "some-name");
|
||||
var writer = new StringWriter();
|
||||
var expected = string.Join("", Enumerable.Range(0, valuesToWrite).Select(_ => "abc"));
|
||||
|
||||
// Act
|
||||
for (var i = 0; i < valuesToWrite; i++)
|
||||
{
|
||||
buffer.AppendHtml("abc");
|
||||
}
|
||||
|
||||
await buffer.WriteToAsync(writer, new HtmlTestEncoder());
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, writer.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue