diff --git a/src/Microsoft.AspNet.Mvc.Razor/RazorTextWriter.cs b/src/Microsoft.AspNet.Mvc.Razor/RazorTextWriter.cs
index 3ca7aef74a..d9be07dbbf 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/RazorTextWriter.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/RazorTextWriter.cs
@@ -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
///
/// The to write output to when this instance
/// is no longer buffering.
- /// The to buffer output to.
+ /// The to buffer output to.
/// The HTML encoder.
- 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
///
/// Gets the buffered content.
///
- public IHtmlContent Buffer => BufferedWriter.ContentBuilder;
+ public ViewBuffer Buffer { get; }
// Internal for unit testing
internal HtmlContentWrapperTextWriter BufferedWriter { get; }
diff --git a/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs b/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs
index d2394a2a0d..81c6e82ecf 100644
--- a/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs
+++ b/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs
@@ -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);
}
}
diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/ViewBuffer.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/ViewBuffer.cs
index a57fa7775e..7bc6f68656 100644
--- a/src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/ViewBuffer.cs
+++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/ViewBuffer.cs
@@ -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;
+ }
+ }
+ }
+ }
+
+ ///
+ /// Writes the buffered content to .
+ ///
+ /// The .
+ /// The .
+ /// A which will complete once content has been written.
+ 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;
+ }
}
}
}
diff --git a/src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/ViewBufferValue.cs b/src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/ViewBufferValue.cs
index 7a29077b2c..e36b7ee0f6 100644
--- a/src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/ViewBufferValue.cs
+++ b/src/Microsoft.AspNet.Mvc.ViewFeatures/Buffer/ViewBufferValue.cs
@@ -35,31 +35,5 @@ namespace Microsoft.AspNet.Mvc.ViewFeatures.Buffer
/// Gets the value.
///
public object Value { get; }
-
- ///
- /// Writes the by encoding it with the specified to the
- /// specified .
- ///
- /// The to write the value to.
- /// The which encodes the content to be written.
- 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);
- }
- }
}
}
diff --git a/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Buffer/ViewBufferTest.cs b/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Buffer/ViewBufferTest.cs
index 979063dd89..df8eb4439d 100644
--- a/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Buffer/ViewBufferTest.cs
+++ b/test/Microsoft.AspNet.Mvc.ViewFeatures.Test/Buffer/ViewBufferTest.cs
@@ -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();
+ 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());
+ }
}
}