public async Task Write_WithHtmlString_WritesValueWithoutEncoding() { // Arrange var writer = new RazorTextWriter(TextWriter.Null, Encoding.UTF8); var stringCollectionWriter = new StringCollectionTextWriter(Encoding.UTF8); stringCollectionWriter.Write("text1"); stringCollectionWriter.Write("text2"); var page = CreatePage(p => { p.Write(new HtmlString("Hello world")); p.Write(new HtmlString(stringCollectionWriter)); }); page.ViewContext.Writer = writer; // Act await page.ExecuteAsync(); // Assert var buffer = writer.BufferedWriter.Buffer; Assert.Equal(2, buffer.BufferEntries.Count); Assert.Equal("Hello world", buffer.BufferEntries[0]); Assert.Same(stringCollectionWriter.Buffer.BufferEntries, buffer.BufferEntries[1]); }
public async Task WriteTagHelperToAsync_WritesFormattedTagHelper(TagHelperOutput output, string expected) { // Arrange var writer = new StringCollectionTextWriter(Encoding.UTF8); var context = CreateViewContext(new StringWriter()); var tagHelperExecutionContext = new TagHelperExecutionContext( tagName: output.TagName, selfClosing: output.SelfClosing, items: new Dictionary <object, object>(), uniqueId: string.Empty, executeChildContentAsync: () => Task.FromResult(result: true), startTagHelperWritingScope: () => { }, endTagHelperWritingScope: () => new DefaultTagHelperContent()); tagHelperExecutionContext.Output = output; // Act var page = CreatePage(p => { p.HtmlEncoder = new HtmlEncoder(); p.WriteTagHelperToAsync(writer, tagHelperExecutionContext).Wait(); }, context); await page.ExecuteAsync(); // Assert Assert.Equal(expected, writer.ToString()); }
private async Task <HtmlString> RenderSectionAsyncCore(string sectionName, bool required) { if (_renderedSections.Contains(sectionName)) { var message = Resources.FormatSectionAlreadyRendered(sectionName); throw new InvalidOperationException(message); } RenderAsyncDelegate renderDelegate; if (PreviousSectionWriters.TryGetValue(sectionName, out renderDelegate)) { _renderedSections.Add(sectionName); using (var writer = new StringCollectionTextWriter(Output.Encoding)) { await renderDelegate(writer); // Returning a disposed StringCollectionTextWriter is safe. return(new HtmlString(writer)); } } else if (required) { // If the section is not found, and it is not optional, throw an error. throw new InvalidOperationException(Resources.FormatSectionNotDefined(sectionName)); } else { // If the section is optional and not found, then don't do anything. return(null); } }
private async Task RenderLayoutAsync(ViewContext context, StringCollectionTextWriter bodyWriter) { // A layout page can specify another layout page. We'll need to continue // looking for layout pages until they're no longer specified. var previousPage = RazorPage; var renderedLayouts = new List <IRazorPage>(); while (!string.IsNullOrEmpty(previousPage.Layout)) { var layoutPage = GetLayoutPage(context, previousPage.Layout); // Notify the previous page that any writes that are performed on it are part of sections being written // in the layout. previousPage.IsLayoutBeingRendered = true; layoutPage.PreviousSectionWriters = previousPage.SectionWriters; layoutPage.RenderBodyDelegate = bodyWriter.CopyTo; bodyWriter = await RenderPageAsync(layoutPage, context, executeViewStart : false); renderedLayouts.Add(layoutPage); previousPage = layoutPage; } // Ensure all defined sections were rendered or RenderBody was invoked for page without defined sections. foreach (var layoutPage in renderedLayouts) { layoutPage.EnsureRenderedBodyOrSections(); } await bodyWriter.CopyToAsync(context.Writer); }
public async Task WriteTagHelperToAsync_WritesToSpecifiedWriter() { // Arrange var writer = new StringCollectionTextWriter(Encoding.UTF8); var context = CreateViewContext(new StringWriter()); var tagHelperExecutionContext = new TagHelperExecutionContext( tagName: "p", selfClosing: false, items: new Dictionary <object, object>(), uniqueId: string.Empty, executeChildContentAsync: () => { return(Task.FromResult(result: true)); }, startTagHelperWritingScope: () => { }, endTagHelperWritingScope: () => new DefaultTagHelperContent()); tagHelperExecutionContext.Output = new TagHelperOutput("p", new Dictionary <string, object>()); tagHelperExecutionContext.Output.Content.SetContent("Hello World!"); // Act var page = CreatePage(p => { p.WriteTagHelperToAsync(writer, tagHelperExecutionContext).Wait(); }, context); await page.ExecuteAsync(); // Assert Assert.Equal("<p>Hello World!</p>", writer.ToString()); }
private async Task <StringCollectionTextWriter> RenderPageAsync(IRazorPage page, ViewContext context, bool executeViewStart) { var bufferedWriter = new StringCollectionTextWriter(context.Writer.Encoding); var writer = (TextWriter)bufferedWriter; // The writer for the body is passed through the ViewContext, allowing things like HtmlHelpers // and ViewComponents to reference it. var oldWriter = context.Writer; var oldFilePath = context.ExecutingFilePath; context.Writer = writer; context.ExecutingFilePath = page.Path; try { if (executeViewStart) { // Execute view starts using the same context + writer as the page to render. await RenderViewStartAsync(context); } await RenderPageCoreAsync(page, context); return(bufferedWriter); } finally { context.Writer = oldWriter; context.ExecutingFilePath = oldFilePath; writer.Dispose(); } }
public void BeginAddHtmlAttributeValues( TagHelperExecutionContext executionContext, string attributeName, int attributeValuesCount) { _tagHelperAttributeInfo = new TagHelperAttributeInfo(executionContext, attributeName, attributeValuesCount); _valueBuffer = null; }
/// <summary> /// Creates a new instance of <see cref="RazorTextWriter"/>. /// </summary> /// <param name="unbufferedWriter">The <see cref="TextWriter"/> to write output to when this instance /// is no longer buffering.</param> /// <param name="encoding">The character <see cref="Encoding"/> in which the output is written.</param> /// <param name="encoder">The HTML encoder.</param> public RazorTextWriter(TextWriter unbufferedWriter, Encoding encoding, IHtmlEncoder encoder) { UnbufferedWriter = unbufferedWriter; HtmlEncoder = encoder; BufferedWriter = new StringCollectionTextWriter(encoding); TargetWriter = BufferedWriter; }
public async Task <IHtmlContent> PartialAsync( [NotNull] string partialViewName) { using (var writer = new StringCollectionTextWriter(Encoding.UTF8)) { await RenderPartialCoreAsync(partialViewName, writer); return(writer.Content); } }
public void AddHtmlAttributeValues( string attributeName, TagHelperExecutionContext executionContext, params AttributeValue[] values) { if (IsSingleBoolFalseOrNullValue(values)) { // The first value was 'null' or 'false' indicating that we shouldn't render the attribute. The // attribute is treated as a TagHelper attribute so it's only available in // TagHelperContext.AllAttributes for TagHelper authors to see (if they want to see why the attribute // was removed from TagHelperOutput.Attributes). executionContext.AddTagHelperAttribute( attributeName, values[0].Value.Value?.ToString() ?? string.Empty); return; } else if (UseAttributeNameAsValue(values)) { executionContext.AddHtmlAttribute(attributeName, attributeName); } else { var valueBuffer = new StringCollectionTextWriter(Output.Encoding); foreach (var value in values) { if (value.Value.Value == null) { // Skip null values continue; } if (!string.IsNullOrEmpty(value.Prefix)) { WriteLiteralTo(valueBuffer, value.Prefix); } WriteUnprefixedAttributeValueTo(valueBuffer, value); } using (var stringWriter = new StringWriter()) { valueBuffer.Content.WriteTo(stringWriter, HtmlEncoder); var htmlString = new HtmlString(stringWriter.ToString()); executionContext.AddHtmlAttribute(attributeName, htmlString); } } }
public async Task WriteLines_WritesCharBuffer() { // Arrange var newLine = Environment.NewLine; var writer = new StringCollectionTextWriter(Encoding.UTF8); // Act writer.WriteLine(); await writer.WriteLineAsync(); // Assert var actual = writer.Entries; Assert.Equal<object>(new[] { newLine, newLine }, actual); }
public void WriteLine_WritesDataTypes_ToBuffer() { // Arrange var newLine = Environment.NewLine; var expected = new List<object> { "False", newLine, "1.1", newLine, "3", newLine }; var writer = new StringCollectionTextWriter(Encoding.UTF8); // Act writer.WriteLine(false); writer.WriteLine(1.1f); writer.WriteLine(3L); // Assert Assert.Equal(expected, writer.Entries); }
public void AddHtmlAttributeValue( string prefix, int prefixOffset, object value, int valueOffset, int valueLength, bool isLiteral) { Debug.Assert(_tagHelperAttributeInfo.ExecutionContext != null); if (_tagHelperAttributeInfo.AttributeValuesCount == 1) { if (IsBoolFalseOrNullValue(prefix, value)) { // The first value was 'null' or 'false' indicating that we shouldn't render the attribute. The // attribute is treated as a TagHelper attribute so it's only available in // TagHelperContext.AllAttributes for TagHelper authors to see (if they want to see why the // attribute was removed from TagHelperOutput.Attributes). _tagHelperAttributeInfo.ExecutionContext.AddTagHelperAttribute( _tagHelperAttributeInfo.Name, value?.ToString() ?? string.Empty); _tagHelperAttributeInfo.Suppressed = true; return; } else if (IsBoolTrueWithEmptyPrefixValue(prefix, value)) { _tagHelperAttributeInfo.ExecutionContext.AddHtmlAttribute( _tagHelperAttributeInfo.Name, _tagHelperAttributeInfo.Name); _tagHelperAttributeInfo.Suppressed = true; return; } } if (value != null) { if (_valueBuffer == null) { _valueBuffer = new StringCollectionTextWriter(Output.Encoding); } if (!string.IsNullOrEmpty(prefix)) { WriteLiteralTo(_valueBuffer, prefix); } WriteUnprefixedAttributeValueTo(_valueBuffer, value, isLiteral); } }
public void Write_WritesDataTypes_ToBuffer() { // Arrange var expected = new[] { "True", "3", "18446744073709551615", "Hello world", "3.14", "2.718", "m" }; var writer = new StringCollectionTextWriter(Encoding.UTF8); // Act writer.Write(true); writer.Write(3); writer.Write(ulong.MaxValue); writer.Write(new TestClass()); writer.Write(3.14); writer.Write(2.718m); writer.Write('m'); // Assert Assert.Equal(expected, writer.Entries); }
private IHtmlContent PerformInvoke(DisplayContext displayContext, MethodInfo methodInfo, object serviceInstance) { using (var output = new StringCollectionTextWriter(System.Text.Encoding.UTF8)) { var arguments = methodInfo .GetParameters() .Select(parameter => BindParameter(displayContext, parameter, output)); // Resolve the service the method is declared on var returnValue = methodInfo.Invoke(serviceInstance, arguments.ToArray()); // If the shape returns a value, write it to the stream if (methodInfo.ReturnType != typeof(void)) { output.Write(CoerceHtmlString(returnValue)); } return(output.Content); } }
public async Task Write_WritesCharBuffer() { // Arrange var input1 = new ArraySegment<char>(new char[] { 'a', 'b', 'c', 'd' }, 1, 3); var input2 = new ArraySegment<char>(new char[] { 'e', 'f' }, 0, 2); var input3 = new ArraySegment<char>(new char[] { 'g', 'h', 'i', 'j' }, 3, 1); var writer = new StringCollectionTextWriter(Encoding.UTF8); // Act writer.Write(input1.Array, input1.Offset, input1.Count); await writer.WriteAsync(input2.Array, input2.Offset, input2.Count); await writer.WriteLineAsync(input3.Array, input3.Offset, input3.Count); // Assert var buffer = writer.Entries; Assert.Equal(4, buffer.Count); Assert.Equal("bcd", buffer[0]); Assert.Equal("ef", buffer[1]); Assert.Equal("j", buffer[2]); Assert.Equal(Environment.NewLine, buffer[3]); }
private async Task <IHtmlContent> RenderRazorViewAsync(string path, DisplayContext context) { var viewEngineResult = _viewEngine.Value.ViewEngines.First().FindPartialView(_actionContextAccessor.ActionContext, path); if (viewEngineResult.Success) { using (var writer = new StringCollectionTextWriter(context.ViewContext.Writer.Encoding)) { // Forcing synchronous behavior so users don't have to await templates. var view = viewEngineResult.View; using (view as IDisposable) { var viewContext = new ViewContext(context.ViewContext, viewEngineResult.View, context.ViewContext.ViewData, writer); await viewEngineResult.View.RenderAsync(viewContext); return(writer.Content); } } } return(null); }
public IHtmlContent Render() { var defaultActions = GetDefaultActions(); var modeViewPath = _readOnly ? DisplayTemplateViewPath : EditorTemplateViewPath; foreach (string viewName in GetViewNames()) { var fullViewName = modeViewPath + "/" + viewName; var viewEngineResult = _viewEngine.FindPartialView(_viewContext, fullViewName); if (viewEngineResult.Success) { using (var writer = new StringCollectionTextWriter(_viewContext.Writer.Encoding)) { // Forcing synchronous behavior so users don't have to await templates. var view = viewEngineResult.View; using (view as IDisposable) { var viewContext = new ViewContext(_viewContext, viewEngineResult.View, _viewData, writer); var renderTask = viewEngineResult.View.RenderAsync(viewContext); renderTask.GetAwaiter().GetResult(); return(writer.Content); } } } Func <IHtmlHelper, IHtmlContent> defaultAction; if (defaultActions.TryGetValue(viewName, out defaultAction)) { return(defaultAction(MakeHtmlHelper(_viewContext, _viewData))); } } throw new InvalidOperationException( Resources.FormatTemplateHelpers_NoTemplate(_viewData.ModelExplorer.ModelType.FullName)); }
public async Task WriteTagHelperAsync_WritesContentAppropriately( bool childContentRetrieved, string input, string expected) { // Arrange var defaultTagHelperContent = new DefaultTagHelperContent(); var writer = new StringCollectionTextWriter(Encoding.UTF8); var context = CreateViewContext(writer); var tagHelperExecutionContext = new TagHelperExecutionContext( tagName: "p", selfClosing: false, items: new Dictionary <object, object>(), uniqueId: string.Empty, executeChildContentAsync: () => { defaultTagHelperContent.SetContent(input); return(Task.FromResult(result: true)); }, startTagHelperWritingScope: () => { }, endTagHelperWritingScope: () => defaultTagHelperContent); tagHelperExecutionContext.Output = new TagHelperOutput("p", new Dictionary <string, object>()); if (childContentRetrieved) { await tagHelperExecutionContext.GetChildContentAsync(); } // Act var page = CreatePage(p => { p.HtmlEncoder = new HtmlEncoder(); p.WriteTagHelperAsync(tagHelperExecutionContext).Wait(); }, context); await page.ExecuteAsync(); // Assert Assert.Equal(expected, writer.ToString()); }
public async Task WriteTagHelperToAsync_WritesFormattedTagHelper(TagHelperOutput output, string expected) { // Arrange var writer = new StringCollectionTextWriter(Encoding.UTF8); var context = CreateViewContext(new StringWriter()); var tagHelperExecutionContext = new TagHelperExecutionContext( tagName: output.TagName, tagMode: output.TagMode, items: new Dictionary<object, object>(), uniqueId: string.Empty, executeChildContentAsync: () => Task.FromResult(result: true), startTagHelperWritingScope: () => { }, endTagHelperWritingScope: () => new DefaultTagHelperContent()); tagHelperExecutionContext.Output = output; // Act var page = CreatePage(p => { p.HtmlEncoder = new CommonTestEncoder(); p.WriteTagHelperToAsync(writer, tagHelperExecutionContext).Wait(); }, context); await page.ExecuteAsync(); // Assert Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(writer.Content)); }
public void Copy_CopiesContent_IfTargetTextWriterIsAStringCollectionTextWriter() { // Arrange var source = new StringCollectionTextWriter(Encoding.UTF8); var target = new StringCollectionTextWriter(Encoding.UTF8); // Act source.Write("Hello world"); source.Write(new char[1], 0, 1); source.CopyTo(target, new CommonTestEncoder()); // Assert // Make sure content was written to the source. Assert.Equal(2, source.Entries.Count); Assert.Equal(1, target.Entries.Count); var entry = Assert.Single(target.Entries); Assert.Same(source.Content, entry); }
public async Task WriteTagHelperAsync_WritesContentAppropriately( bool childContentRetrieved, string input, string expected) { // Arrange var defaultTagHelperContent = new DefaultTagHelperContent(); var writer = new StringCollectionTextWriter(Encoding.UTF8); var context = CreateViewContext(writer); var tagHelperExecutionContext = new TagHelperExecutionContext( tagName: "p", tagMode: TagMode.StartTagAndEndTag, items: new Dictionary<object, object>(), uniqueId: string.Empty, executeChildContentAsync: () => { defaultTagHelperContent.AppendEncoded(input); return Task.FromResult(result: true); }, startTagHelperWritingScope: () => { }, endTagHelperWritingScope: () => defaultTagHelperContent); tagHelperExecutionContext.Output = new TagHelperOutput("p", new TagHelperAttributeList()); if (childContentRetrieved) { await tagHelperExecutionContext.GetChildContentAsync(useCachedResult: true); } // Act var page = CreatePage(p => { p.HtmlEncoder = new CommonTestEncoder(); p.WriteTagHelperAsync(tagHelperExecutionContext).Wait(); }, context); await page.ExecuteAsync(); // Assert Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(writer.Content)); }
public async Task WriteTagHelperToAsync_WritesToSpecifiedWriter() { // Arrange var writer = new StringCollectionTextWriter(Encoding.UTF8); var context = CreateViewContext(new StringWriter()); var tagHelperExecutionContext = new TagHelperExecutionContext( tagName: "p", tagMode: TagMode.StartTagAndEndTag, items: new Dictionary<object, object>(), uniqueId: string.Empty, executeChildContentAsync: () => { return Task.FromResult(result: true); }, startTagHelperWritingScope: () => { }, endTagHelperWritingScope: () => new DefaultTagHelperContent()); tagHelperExecutionContext.Output = new TagHelperOutput("p", new TagHelperAttributeList()); tagHelperExecutionContext.Output.Content.AppendEncoded("Hello World!"); // Act var page = CreatePage(p => { p.HtmlEncoder = new CommonTestEncoder(); p.WriteTagHelperToAsync(writer, tagHelperExecutionContext).Wait(); }, context); await page.ExecuteAsync(); // Assert Assert.Equal("<p>Hello World!</p>", HtmlContentUtilities.HtmlContentToString(writer.Content)); }
private async Task<IHtmlContent> RenderRazorViewAsync(string path, DisplayContext context) { var viewEngineResult = _viewEngine.Value.ViewEngines.First().FindPartialView(_actionContextAccessor.ActionContext, path); if (viewEngineResult.Success) { using (var writer = new StringCollectionTextWriter(context.ViewContext.Writer.Encoding)) { // Forcing synchronous behavior so users don't have to await templates. var view = viewEngineResult.View; using (view as IDisposable) { var viewContext = new ViewContext(context.ViewContext, viewEngineResult.View, context.ViewContext.ViewData, writer); await viewEngineResult.View.RenderAsync(viewContext); return writer.Content; } } } return null; }
public void Copy_WritesContent_IfTargetTextWriterIsNotAStringCollectionTextWriter() { // Arrange var source = new StringCollectionTextWriter(Encoding.UTF8); var target = new StringWriter(); var expected = @"Hello world" + Environment.NewLine + "abc"; // Act source.WriteLine("Hello world"); source.Write(new[] { 'x', 'a', 'b', 'c' }, 1, 3); source.CopyTo(target, new CommonTestEncoder()); // Assert Assert.Equal(expected, target.ToString()); }
private IHtmlContent PerformInvoke(DisplayContext displayContext, MethodInfo methodInfo, object serviceInstance) { using (var output = new StringCollectionTextWriter(System.Text.Encoding.UTF8)) { var arguments = methodInfo .GetParameters() .Select(parameter => BindParameter(displayContext, parameter, output)); // Resolve the service the method is declared on var returnValue = methodInfo.Invoke(serviceInstance, arguments.ToArray()); // If the shape returns a value, write it to the stream if (methodInfo.ReturnType != typeof(void)) { output.Write(CoerceHtmlString(returnValue)); } return output.Content; } }
public void WriteLine_Object_HtmlContent_AddsToEntries() { // Arrange var writer = new StringCollectionTextWriter(Encoding.UTF8); var content = new HtmlString("Hello, world!"); // Act writer.WriteLine(content); // Assert Assert.Collection( writer.Entries, item => Assert.Same(content, item), item => Assert.Equal(Environment.NewLine, item)); }
public async Task Write_WritesStringBuffer() { // Arrange var newLine = Environment.NewLine; var input1 = "Hello"; var input2 = "from"; var input3 = "ASP"; var input4 = ".Net"; var writer = new StringCollectionTextWriter(Encoding.UTF8); // Act writer.Write(input1); writer.WriteLine(input2); await writer.WriteAsync(input3); await writer.WriteLineAsync(input4); // Assert var actual = writer.Entries; Assert.Equal(new[] { input1, input2, newLine, input3, input4, newLine }, actual); }