Exemple #1
0
        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]);
        }
Exemple #2
0
        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());
        }
Exemple #3
0
        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);
            }
        }
Exemple #4
0
        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);
        }
Exemple #5
0
        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());
        }
Exemple #6
0
        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();
            }
        }
Exemple #7
0
 public void BeginAddHtmlAttributeValues(
     TagHelperExecutionContext executionContext,
     string attributeName,
     int attributeValuesCount)
 {
     _tagHelperAttributeInfo = new TagHelperAttributeInfo(executionContext, attributeName, attributeValuesCount);
     _valueBuffer            = null;
 }
Exemple #8
0
        /// <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;
        }
Exemple #9
0
        public async Task <IHtmlContent> PartialAsync(
            [NotNull] string partialViewName)
        {
            using (var writer = new StringCollectionTextWriter(Encoding.UTF8))
            {
                await RenderPartialCoreAsync(partialViewName, writer);

                return(writer.Content);
            }
        }
Exemple #10
0
        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);
        }
Exemple #13
0
        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]);
        }
Exemple #17
0
        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);
        }
Exemple #18
0
        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));
        }
Exemple #19
0
        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());
        }
Exemple #20
0
        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);
        }
Exemple #22
0
        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));
        }
Exemple #23
0
        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);
        }