Remove TextWriter.ToString from RazorPage

Fixes #3668
This commit is contained in:
Pranav K 2015-12-18 08:45:37 -08:00
parent c5b6efd6bf
commit 5f66403248
3 changed files with 8 additions and 144 deletions

View File

@ -30,7 +30,7 @@ namespace Microsoft.AspNet.Mvc.Razor
public abstract class RazorPage : IRazorPage
{
private readonly HashSet<string> _renderedSections = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
private readonly Stack<TextWriter> _writerScopes;
private readonly Stack<HtmlContentWrapperTextWriter> _writerScopes;
private TextWriter _originalWriter;
private IUrlHelper _urlHelper;
private ITagHelperActivator _tagHelperActivator;
@ -44,7 +44,7 @@ namespace Microsoft.AspNet.Mvc.Razor
public RazorPage()
{
SectionWriters = new Dictionary<string, RenderAsyncDelegate>(StringComparer.OrdinalIgnoreCase);
_writerScopes = new Stack<TextWriter>();
_writerScopes = new Stack<HtmlContentWrapperTextWriter>();
}
/// <summary>
@ -209,30 +209,15 @@ namespace Microsoft.AspNet.Mvc.Razor
/// </remarks>
public void StartTagHelperWritingScope()
{
var buffer = new ViewBuffer(BufferScope, Path);
StartTagHelperWritingScope(new HtmlContentWrapperTextWriter(buffer, Output.Encoding));
}
/// <summary>
/// Starts a new writing scope with the given <paramref name="writer"/>.
/// </summary>
/// <remarks>
/// All writes to the <see cref="Output"/> or <see cref="ViewContext.Writer"/> after calling this method will
/// be buffered until <see cref="EndTagHelperWritingScope"/> is called.
/// </remarks>
public void StartTagHelperWritingScope(TextWriter writer)
{
if (writer == null)
{
throw new ArgumentNullException(nameof(writer));
}
// If there isn't a base writer take the ViewContext.Writer
if (_originalWriter == null)
{
_originalWriter = ViewContext.Writer;
}
var buffer = new ViewBuffer(BufferScope, Path);
var writer = new HtmlContentWrapperTextWriter(buffer, _originalWriter.Encoding);
// We need to replace the ViewContext's Writer to ensure that all content (including content written
// from HTML helpers) is redirected.
ViewContext.Writer = writer;
@ -243,8 +228,7 @@ namespace Microsoft.AspNet.Mvc.Razor
/// <summary>
/// Ends the current writing scope that was started by calling <see cref="StartTagHelperWritingScope"/>.
/// </summary>
/// <returns>The <see cref="TextWriter"/> that contains the content written to the <see cref="Output"/> or
/// <see cref="ViewContext.Writer"/> during the writing scope.</returns>
/// <returns>The buffered <see cref="TagHelperContent"/>.</returns>
public TagHelperContent EndTagHelperWritingScope()
{
if (_writerScopes.Count == 0)
@ -253,6 +237,7 @@ namespace Microsoft.AspNet.Mvc.Razor
}
var writer = _writerScopes.Pop();
Debug.Assert(writer == ViewContext.Writer);
if (_writerScopes.Count > 0)
{
@ -267,24 +252,7 @@ namespace Microsoft.AspNet.Mvc.Razor
}
var tagHelperContent = new DefaultTagHelperContent();
var razorWriter = writer as RazorTextWriter;
if (razorWriter != null)
{
tagHelperContent.Append(razorWriter.Buffer);
}
else
{
var htmlContentTextWriter = writer as HtmlContentWrapperTextWriter;
if (htmlContentTextWriter != null)
{
tagHelperContent.Append(htmlContentTextWriter.ContentBuilder);
}
else
{
tagHelperContent.AppendHtml(writer.ToString());
}
}
tagHelperContent.Append(writer.ContentBuilder);
return tagHelperContent;
}

View File

@ -1,78 +0,0 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Text;
using Microsoft.AspNet.Html;
using Microsoft.AspNet.Razor.TagHelpers;
namespace Microsoft.AspNet.Mvc.Razor
{
/// <summary>
/// <see cref="HtmlTextWriter"/> implementation which writes to a <see cref="TagHelperContent"/> instance.
/// </summary>
public class TagHelperContentWrapperTextWriter : HtmlTextWriter
{
/// <summary>
/// Initializes a new instance of the <see cref="TagHelperContentWrapperTextWriter"/> class.
/// </summary>
/// <param name="encoding">The <see cref="Encoding"/> in which output is written.</param>
public TagHelperContentWrapperTextWriter(Encoding encoding)
: this(encoding, new DefaultTagHelperContent())
{
}
/// <summary>
/// Initializes a new instance of the <see cref="TagHelperContentWrapperTextWriter"/> class.
/// </summary>
/// <param name="encoding">The <see cref="Encoding"/> in which output is written.</param>
/// <param name="content">The <see cref="TagHelperContent"/> to write to.</param>
public TagHelperContentWrapperTextWriter(Encoding encoding, TagHelperContent content)
{
if (encoding == null)
{
throw new ArgumentNullException(nameof(encoding));
}
if (content == null)
{
throw new ArgumentNullException(nameof(content));
}
Content = content;
Encoding = encoding;
}
/// <summary>
/// The <see cref="TagHelperContent"/> this <see cref="TagHelperContentWrapperTextWriter"/> writes to.
/// </summary>
public TagHelperContent Content { get; }
/// <inheritdoc />
public override Encoding Encoding { get; }
/// <inheritdoc />
public override void Write(string value)
{
Content.AppendHtml(value);
}
/// <inheritdoc />
public override void Write(char value)
{
Content.AppendHtml(value.ToString());
}
/// <inheritdoc />
public override void Write(IHtmlContent value)
{
Content.Append(value);
}
/// <inheritdoc />
public override string ToString()
{
return Content.ToString();
}
}
}

View File

@ -175,32 +175,6 @@ namespace Microsoft.AspNet.Mvc.Razor
await page.ExecuteAsync();
}
[Fact]
public async Task EndTagHelperWritingScope_CopiesContent_IfRazorTextWriter()
{
// Arrange
var viewContext = CreateViewContext();
// Act
var page = CreatePage(v =>
{
v.HtmlEncoder = new HtmlTestEncoder();
var buffer = new ViewBuffer(new TestViewBufferScope(), v.Path);
v.StartTagHelperWritingScope(new RazorTextWriter(TextWriter.Null, buffer, v.HtmlEncoder));
v.Write("Hello ");
v.Write("World!");
var returnValue = v.EndTagHelperWritingScope();
// Assert
var content = Assert.IsType<DefaultTagHelperContent>(returnValue);
Assert.Equal("HtmlEncode[[Hello ]]HtmlEncode[[World!]]", content.GetContent());
Assert.Equal(
"HtmlEncode[[Hello ]]HtmlEncode[[World!]]",
HtmlContentUtilities.HtmlContentToString(content));
}, viewContext);
await page.ExecuteAsync();
}
[Fact]
public async Task DefineSection_ThrowsIfSectionIsAlreadyDefined()
{