Exemple #1
0
        public void Append_CreatesNewPages_WhenCurrentPageIsFull()
        {
            // Arrange
            var buffer = new ViewBuffer(new TestViewBufferScope(), "some-name", pageSize: 32);
            var expected = Enumerable.Range(0, 32).Select(i => i.ToString());

            // Act
            foreach (var item in expected)
            {
                buffer.AppendHtml(item);
            }
            buffer.AppendHtml("Hello");
            buffer.AppendHtml("world");

            // Assert
            Assert.Equal(2, buffer.Pages.Count);
            Assert.Collection(buffer.Pages,
                page => Assert.Equal(expected, page.Buffer.Select(v => v.Value)),
                page =>
                {
                    var array = page.Buffer;
                    Assert.Equal("Hello", array[0].Value);
                    Assert.Equal("world", array[1].Value);
                });
        }
        /// <summary>
        /// Creates a new instance of <see cref="ViewBufferTextWriter"/>.
        /// </summary>
        /// <param name="buffer">The <see cref="ViewBuffer"/> for buffered output.</param>
        /// <param name="encoding">The <see cref="System.Text.Encoding"/>.</param>
        /// <param name="htmlEncoder">The HTML encoder.</param>
        /// <param name="inner">
        /// The inner <see cref="TextWriter"/> to write output to when this instance is no longer buffering.
        /// </param>
        public ViewBufferTextWriter(ViewBuffer buffer, Encoding encoding, HtmlEncoder htmlEncoder, TextWriter inner)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            if (encoding == null)
            {
                throw new ArgumentNullException(nameof(encoding));
            }

            if (htmlEncoder == null)
            {
                throw new ArgumentNullException(nameof(htmlEncoder));
            }

            if (inner == null)
            {
                throw new ArgumentNullException(nameof(inner));
            }

            Buffer = buffer;
            Encoding = encoding;
            _htmlEncoder = htmlEncoder;
            _inner = inner;
        }
Exemple #3
0
        public void Append_AddsEncodingWrapper()
        {
            // Arrange
            var buffer = new ViewBuffer(new TestViewBufferScope(), "some-name", pageSize: 32);

            // Act
            buffer.Append("Hello world");

            // Assert
            var page = Assert.Single(buffer.Pages);
            Assert.Equal(1, page.Count);
            Assert.IsAssignableFrom<IHtmlContent>(page.Buffer[0].Value);
        }
Exemple #4
0
        public void AppendHtml_AddsHtmlContentRazorValue()
        {
            // Arrange
            var buffer = new ViewBuffer(new TestViewBufferScope(), "some-name", pageSize: 32);
            var content = new HtmlString("hello-world");

            // Act
            buffer.AppendHtml(content);

            // Assert
            var page = Assert.Single(buffer.Pages);
            Assert.Equal(1, page.Count);
            Assert.Same(content, page.Buffer[0].Value);
        }
Exemple #5
0
        public void AppendHtml_AddsString()
        {
            // Arrange
            var buffer = new ViewBuffer(new TestViewBufferScope(), "some-name", pageSize: 32);
            var value = "Hello world";

            // Act
            buffer.AppendHtml(value);

            // Assert
            var page = Assert.Single(buffer.Pages);
            Assert.Equal(1, page.Count);
            Assert.Equal("Hello world", Assert.IsType<string>(page.Buffer[0].Value));
        }
        /// <summary>
        /// Creates a new instance of <see cref="ViewBufferTextWriter"/>.
        /// </summary>
        /// <param name="buffer">The <see cref="ViewBuffer"/> for buffered output.</param>
        /// <param name="encoding">The <see cref="System.Text.Encoding"/>.</param>
        public ViewBufferTextWriter(ViewBuffer buffer, Encoding encoding)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException(nameof(buffer));
            }

            if (encoding == null)
            {
                throw new ArgumentNullException(nameof(encoding));
            }

            Buffer = buffer;
            Encoding = encoding;
        }
Exemple #7
0
        /// <inheritdoc />
        public async Task <IHtmlContent> PartialAsync(
            string partialViewName,
            object model,
            ViewDataDictionary viewData)
        {
            if (partialViewName == null)
            {
                throw new ArgumentNullException(nameof(partialViewName));
            }

            var viewBuffer = new ViewBuffer(_bufferScope, partialViewName, ViewBuffer.PartialViewPageSize);

            using (var writer = new ViewBufferTextWriter(viewBuffer, Encoding.UTF8))
            {
                await RenderPartialCoreAsync(partialViewName, model, viewData, writer);

                return(viewBuffer);
            }
        }
Exemple #8
0
        public async Task Write_WithHtmlString_WritesValueWithoutEncoding()
        {
            // Arrange
            var buffer = new ViewBuffer(new TestViewBufferScope(), string.Empty, pageSize: 32);
            var writer = new ViewBufferTextWriter(buffer, Encoding.UTF8);

            var page = CreatePage(p =>
            {
                p.Write(new HtmlString("Hello world"));
            });

            page.PageContext.Writer = writer;

            // Act
            await page.ExecuteAsync();

            // Assert
            Assert.Equal("Hello world", HtmlContentUtilities.HtmlContentToString(buffer));
        }
Exemple #9
0
    public void MoveTo_ViewBuffer_TakesPage_IfOriginalIsEmpty()
    {
        // Arrange
        var scope = new TestViewBufferScope();

        var original = new ViewBuffer(scope, "original", pageSize: 4);
        var other    = new ViewBuffer(scope, "other", pageSize: 4);

        other.AppendHtml("Hi");

        var page = other[0];

        // Act
        other.MoveTo(original);

        // Assert
        Assert.Equal(0, other.Count); // Page was taken
        Assert.Equal(1, original.Count);
        Assert.Same(page, original[0]);
    }
Exemple #10
0
    [InlineData(65)]            // Create many pages before clear
    public void Clear_ResetsBackingBufferAndIndex(int valuesToWrite)
    {
        // Arrange
        var buffer = new ViewBuffer(new TestViewBufferScope(), "some-name", pageSize: 32);

        // Act
        for (var i = 0; i < valuesToWrite; i++)
        {
            buffer.AppendHtml("Hello");
        }
        buffer.Clear();
        buffer.AppendHtml("world");

        // Assert
        Assert.Equal(1, buffer.Count);
        var page = buffer[0];

        Assert.Equal(1, page.Count);
        Assert.Equal("world", page.Buffer[0].Value);
    }
        public IHtmlContent Render()
        {
            var defaultActions = GetDefaultActions();
            var modeViewPath   = _readOnly ? DisplayTemplateViewPath : EditorTemplateViewPath;

            foreach (string viewName in GetViewNames())
            {
                var viewEngineResult = _viewEngine.GetView(_viewContext.ExecutingFilePath, viewName, isMainPage: false);
                if (!viewEngineResult.Success)
                {
                    var fullViewName = modeViewPath + "/" + viewName;
                    viewEngineResult = _viewEngine.FindView(_viewContext, fullViewName, isMainPage: false);
                }

                if (viewEngineResult.Success)
                {
                    var viewBuffer = new ViewBuffer(_bufferScope, viewName);
                    using (var writer = new HtmlContentWrapperTextWriter(viewBuffer, _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.ContentBuilder);
                        }
                    }
                }

                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));
        }
        async Task <ViewBufferTextWriter> RenderPageAsync(IViewBufferScope bufferScope, IRazorPage page, ViewRenderingContext viewRenderingContext)
        {
            var writer = viewRenderingContext.Writer as ViewBufferTextWriter;

            if (writer == null)
            {
                // If we get here, this is likely the top-level page (not a partial) - this means
                // that context.Writer is wrapping the output stream. We need to buffer, so create a buffered writer.
                var buffer = new ViewBuffer(bufferScope, page.GetType().AssemblyQualifiedName, ViewBuffer.ViewPageSize);
                writer = new ViewBufferTextWriter(buffer, viewRenderingContext.Writer.Encoding, this.htmlEncoder, viewRenderingContext.Writer);
            }
            else
            {
                // This means we're writing something like a partial, where the output needs to be buffered.
                // Create a new buffer, but without the ability to flush.
                var buffer = new ViewBuffer(bufferScope, page.GetType().AssemblyQualifiedName, ViewBuffer.ViewPageSize);
                writer = new ViewBufferTextWriter(buffer, viewRenderingContext.Writer.Encoding);
            }

            // The writer for the body is passed through the ViewContext, allowing things like HtmlHelpers
            // and ViewComponents to reference it.
            var oldWriter = viewRenderingContext.Writer;

            //var oldFilePath = context.ExecutingFilePath;

            viewRenderingContext.Writer = writer;
            //context.ExecutingFilePath = page.Path;

            try
            {
                page.RenderingContext = viewRenderingContext;
                await page.ExecuteAsync();

                return(writer);
            }
            finally
            {
                viewRenderingContext.Writer = oldWriter;
                //context.ExecutingFilePath = oldFilePath;
            }
        }
    public async Task Write_WritesDataTypes_AfterFlush()
    {
        // Arrange
        var expected = new object[] { "True", "3", "18446744073709551615", "Hello world", "3.14", "2.718", "m" };
        var buffer   = new ViewBuffer(new TestViewBufferScope(), "some-name", pageSize: 4);
        var writer   = new ViewBufferTextWriter(buffer, Encoding.UTF8);

        // Act
        await writer.FlushAsync();

        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, GetValues(buffer));
    }
        private async Task <IHtmlContent> InvokeCoreAsync(ViewComponentDescriptor descriptor, object arguments)
        {
            var argumentDictionary = GetArgumentDictionary(descriptor, arguments);

            var viewBuffer = new ViewBuffer(_viewBufferScope, descriptor.FullName, ViewBuffer.ViewComponentPageSize);

            using (var writer = new ViewBufferTextWriter(viewBuffer, _viewContext.Writer.Encoding))
            {
                var context = new ViewComponentContext(descriptor, argumentDictionary, _htmlEncoder, _viewContext, writer);

                var invoker = _invokerFactory.CreateInstance(context);
                if (invoker == null)
                {
                    throw new InvalidOperationException($"ViewComponentFactory_ReturnedNull:{descriptor.FullName}");
                }

                await invoker.InvokeAsync(context);

                return(viewBuffer);
            }
        }
        public void WriteLine_WritesDataTypes_ToUnbufferedStream_WhenNotBuffering()
        {
            // Arrange
            var unbufferedWriter = new Mock <TextWriter>();

            unbufferedWriter.SetupGet(w => w.Encoding).Returns(Encoding.UTF8);
            var buffer = new ViewBuffer(new TestViewBufferScope(), "some-name");
            var writer = new RazorTextWriter(unbufferedWriter.Object, buffer, new HtmlTestEncoder());

            // Act
            writer.Flush();
            writer.WriteLine(false);
            writer.WriteLine(1.1f);
            writer.WriteLine(3L);

            // Assert
            Assert.Null(buffer.BufferSegments);
            unbufferedWriter.Verify(v => v.Write("False"), Times.Once());
            unbufferedWriter.Verify(v => v.Write("1.1"), Times.Once());
            unbufferedWriter.Verify(v => v.Write("3"), Times.Once());
            unbufferedWriter.Verify(v => v.WriteLine(), Times.Exactly(3));
        }
Exemple #16
0
    public void MoveTo_FlattensAndClears()
    {
        // Arrange
        var buffer = new ViewBuffer(new TestViewBufferScope(), "some-name", pageSize: 4);

        var nestedItems = new List <object>();
        var nested      = new HtmlContentBuilder(nestedItems);

        nested.AppendHtml("Hello");
        buffer.AppendHtml(nested);

        var destinationItems = new List <object>();
        var destination      = new HtmlContentBuilder(destinationItems);

        // Act
        buffer.MoveTo(destination);

        // Assert
        Assert.Empty(nestedItems);
        Assert.Equal(0, buffer.Count);
        Assert.Equal("Hello", Assert.IsType <HtmlString>(destinationItems[0]).Value);
    }
Exemple #17
0
        private async Task<IHtmlContent> RenderRazorViewAsync(string path, DisplayContext context)
        {
            var viewEngineResult = _viewEngine.Value.ViewEngines.First().FindView(_actionContextAccessor.ActionContext, path, isMainPage: false);
            if (viewEngineResult.Success)
            {
                var bufferScope = context.ViewContext.HttpContext.RequestServices.GetRequiredService<IViewBufferScope>();
                var viewBuffer = new ViewBuffer(bufferScope, viewEngineResult.ViewName, ViewBuffer.PartialViewPageSize);
                using (var writer = new ViewBufferTextWriter(viewBuffer, 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 viewBuffer;
                    }
                }
            }

            return null;
        }
Exemple #18
0
    private void MoveTo(ViewBuffer destination)
    {
        for (var i = 0; i < Count; i++)
        {
            var page = this[i];

            var destinationPage = destination.Count == 0 ? null : destination[destination.Count - 1];

            // If the source page is less or equal to than half full, let's copy it's content to the destination
            // page if possible.
            var isLessThanHalfFull = 2 * page.Count <= page.Capacity;
            if (isLessThanHalfFull &&
                destinationPage != null &&
                destinationPage.Capacity - destinationPage.Count >= page.Count)
            {
                // We have room, let's copy the items.
                Array.Copy(
                    sourceArray: page.Buffer,
                    sourceIndex: 0,
                    destinationArray: destinationPage.Buffer,
                    destinationIndex: destinationPage.Count,
                    length: page.Count);

                destinationPage.Count += page.Count;

                // Now we can return the source page, and it can be reused in the scope of this request.
                Array.Clear(page.Buffer, 0, page.Count);
                _bufferScope.ReturnSegment(page.Buffer);
            }
            else
            {
                // Otherwise, let's just add the source page to the other buffer.
                destination.AddPage(page);
            }
        }

        Clear();
    }
    public async Task Write_WritesStringBuffer()
    {
        // Arrange
        var newLine = Environment.NewLine;
        var input1  = "Hello";
        var input2  = "from";
        var input3  = "ASP";
        var input4  = ".Net";
        var buffer  = new ViewBuffer(new TestViewBufferScope(), "some-name", pageSize: 4);
        var writer  = new ViewBufferTextWriter(buffer, Encoding.UTF8);

        // Act
        writer.Write(input1);
        writer.WriteLine(input2);
        await writer.WriteAsync(input3);

        await writer.WriteLineAsync(input4);

        // Assert
        var actual = GetValues(buffer);

        Assert.Equal <object>(new[] { input1, input2, newLine, input3, input4, newLine }, actual);
    }
Exemple #20
0
        /// <inheritdoc />
        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (output == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var viewBuffer = new ViewBuffer(_viewBufferScope, Name, ViewBuffer.PartialViewPageSize);

            using (var writer = new ViewBufferTextWriter(viewBuffer, Encoding.UTF8))
            {
                await RenderPartialViewAsync(writer);

                // Reset the TagName. We don't want `partial` to render.
                output.TagName = null;
                output.Content.SetHtmlContent(viewBuffer);
            }
        }
Exemple #21
0
        private async Task <IHtmlContent> RenderRazorViewAsync(string viewName, DisplayContext context)
        {
            var viewEngines = _viewEngine.Value.ViewEngines;

            if (viewEngines.Count == 0)
            {
                throw new InvalidOperationException(string.Format("'{0}.{1}' must not be empty. At least one '{2}' is required to locate a view for rendering.",
                                                                  typeof(MvcViewOptions).FullName,
                                                                  nameof(MvcViewOptions.ViewEngines),
                                                                  typeof(IViewEngine).FullName));
            }

            for (var i = 0; i < viewEngines.Count; i++)
            {
                var viewEngineResult = viewEngines[0].FindView(context.ViewContext, viewName, isMainPage: false);
                if (viewEngineResult.Success)
                {
                    var bufferScope = context.ViewContext.HttpContext.RequestServices.GetRequiredService <IViewBufferScope>();
                    var viewBuffer  = new ViewBuffer(bufferScope, viewEngineResult.ViewName, ViewBuffer.PartialViewPageSize);
                    using (var writer = new ViewBufferTextWriter(viewBuffer, 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(viewBuffer);
                        }
                    }
                }
            }

            return(null);
        }
Exemple #22
0
        private async Task <RazorTextWriter> RenderPageAsync(
            IRazorPage page,
            ViewContext context,
            bool invokeViewStarts)
        {
            Debug.Assert(_bufferScope != null);
            var buffer          = new ViewBuffer(_bufferScope, page.Path);
            var razorTextWriter = new RazorTextWriter(context.Writer, buffer, _htmlEncoder);

            // 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            = razorTextWriter;
            context.ExecutingFilePath = page.Path;

            try
            {
                if (invokeViewStarts)
                {
                    // Execute view starts using the same context + writer as the page to render.
                    await RenderViewStartsAsync(context);
                }

                await RenderPageCoreAsync(page, context);

                return(razorTextWriter);
            }
            finally
            {
                context.Writer            = oldWriter;
                context.ExecutingFilePath = oldFilePath;
                razorTextWriter.Dispose();
            }
        }
Exemple #23
0
    public void MoveTo_ViewBuffer_CopiesItems_IfCurrentPageHasRoom()
    {
        // Arrange
        var scope = new TestViewBufferScope();

        var original = new ViewBuffer(scope, "original", pageSize: 4);
        var other    = new ViewBuffer(scope, "other", pageSize: 4);

        for (var i = 0; i < 2; i++)
        {
            original.AppendHtml($"original-{i}");
        }

        // With two items, this is half full so we try to copy the items.
        for (var i = 0; i < 2; i++)
        {
            other.AppendHtml($"other-{i}");
        }

        var page = other[0];

        // Act
        other.MoveTo(original);

        // Assert
        Assert.Equal(0, other.Count);                        // Other is cleared
        Assert.Contains(page.Buffer, scope.ReturnedBuffers); // Buffer was returned

        Assert.Equal(1, original.Count);
        Assert.Collection(
            original[0].Buffer,
            item => Assert.Equal("original-0", item.Value),
            item => Assert.Equal("original-1", item.Value),
            item => Assert.Equal("other-0", item.Value),
            item => Assert.Equal("other-1", item.Value));
    }
Exemple #24
0
        private static ViewContext CreateViewContext(
            TextWriter writer = null,
            IViewBufferScope bufferScope = null,
            string viewPath = null)
        {
            bufferScope = bufferScope ?? new TestViewBufferScope();
            var buffer = new ViewBuffer(bufferScope, viewPath ?? "TEST", 32);
            writer = writer ?? new ViewBufferTextWriter(buffer, Encoding.UTF8);

            var httpContext = new DefaultHttpContext();
            var serviceProvider = new ServiceCollection()
                .AddSingleton<IViewBufferScope>(bufferScope)
                .BuildServiceProvider();
            httpContext.RequestServices = serviceProvider;
            var actionContext = new ActionContext(
                httpContext,
                new RouteData(),
                new ActionDescriptor());
            var viewMock = new Mock<IView>();
            if (!string.IsNullOrEmpty(viewPath))
            {
                viewMock.Setup(v => v.Path).Returns(viewPath);
            }
            return new ViewContext(
                actionContext,
                viewMock.Object,
                new ViewDataDictionary(new EmptyModelMetadataProvider()),
                Mock.Of<ITempDataDictionary>(),
                writer,
                new HtmlHelperOptions());
        }
Exemple #25
0
        public void MoveTo_ViewBuffer_CopiesItems_IfCurrentPageHasRoom()
        {
            // Arrange
            var scope = new TestViewBufferScope();

            var original = new ViewBuffer(scope, "original", pageSize: 4);
            var other = new ViewBuffer(scope, "other", pageSize: 4);

            for (var i = 0; i < 2; i++)
            {
                original.AppendHtml($"original-{i}");
            }

            // With two items, this is half full so we try to copy the items.
            for (var i = 0; i < 2; i++)
            {
                other.AppendHtml($"other-{i}");
            }

            var page = other.Pages[0];

            // Act
            other.MoveTo(original);

            // Assert
            Assert.Empty(other.Pages); // Other is cleared
            Assert.Contains(page.Buffer, scope.ReturnedBuffers); // Buffer was returned

            Assert.Collection(
                Assert.Single(original.Pages).Buffer,
                item => Assert.Equal("original-0", item.Value),
                item => Assert.Equal("original-1", item.Value),
                item => Assert.Equal("other-0", item.Value),
                item => Assert.Equal("other-1", item.Value));
        }
Exemple #26
0
        public void MoveTo_ViewBuffer_TakesPage_IfCurrentPageDoesNotHaveCapacity()
        {
            // Arrange
            var scope = new TestViewBufferScope();

            var original = new ViewBuffer(scope, "original", pageSize: 4);
            var other = new ViewBuffer(scope, "other", pageSize: 4);

            for (var i = 0; i < 3; i++)
            {
                original.AppendHtml($"original-{i}");
            }

            // With two items, we'd try to copy the items, but there's no room in the current page.
            // So we just take over the page.
            for (var i = 0; i < 2; i++)
            {
                other.AppendHtml($"other-{i}");
            }

            var page = other.Pages[0];

            // Act
            other.MoveTo(original);

            // Assert
            Assert.Empty(other.Pages); // Page was taken
            Assert.Equal(2, original.Pages.Count);
            Assert.Same(page, original.Pages[1]);
        }
Exemple #27
0
        public void MoveTo_ViewBuffer_TakesPage_IfCurrentPageInOriginalIsFull()
        {
            // Arrange
            var scope = new TestViewBufferScope();

            var original = new ViewBuffer(scope, "original", pageSize: 4);
            var other = new ViewBuffer(scope, "other", pageSize: 4);

            for (var i = 0; i < 4; i++)
            {
                original.AppendHtml($"original-{i}");
            }

            other.AppendHtml("Hi");

            var page = other.Pages[0];

            // Act
            other.MoveTo(original);

            // Assert
            Assert.Empty(other.Pages); // Page was taken
            Assert.Equal(2, original.Pages.Count);
            Assert.Same(page, original.Pages[1]);
        }
Exemple #28
0
        private async Task<ViewBufferTextWriter> RenderPageAsync(
            IRazorPage page,
            ViewContext context,
            bool invokeViewStarts)
        {
            var writer = context.Writer as ViewBufferTextWriter;
            if (writer == null)
            {
                Debug.Assert(_bufferScope != null);

                // If we get here, this is likely the top-level page (not a partial) - this means
                // that context.Writer is wrapping the output stream. We need to buffer, so create a buffered writer.
                var buffer = new ViewBuffer(_bufferScope, page.Path, ViewBuffer.ViewPageSize);
                writer = new ViewBufferTextWriter(buffer, context.Writer.Encoding, _htmlEncoder, context.Writer);
            }
            else
            {
                // This means we're writing something like a partial, where the output needs to be buffered.
                // Create a new buffer, but without the ability to flush.
                var buffer = new ViewBuffer(_bufferScope, page.Path, ViewBuffer.ViewPageSize);
                writer = new ViewBufferTextWriter(buffer, context.Writer.Encoding);
            }

            // 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 (invokeViewStarts)
                {
                    // Execute view starts using the same context + writer as the page to render.
                    await RenderViewStartsAsync(context);
                }

                await RenderPageCoreAsync(page, context);
                return writer;
            }
            finally
            {
                context.Writer = oldWriter;
                context.ExecutingFilePath = oldFilePath;
            }
        }
Exemple #29
0
        public void Clear_ResetsBackingBufferAndIndex(int valuesToWrite)
        {
            // Arrange
            var buffer = new ViewBuffer(new TestViewBufferScope(), "some-name", pageSize: 32);

            // Act
            for (var i = 0; i < valuesToWrite; i++)
            {
                buffer.AppendHtml("Hello");
            }
            buffer.Clear();
            buffer.AppendHtml("world");

            // Assert
            var page = Assert.Single(buffer.Pages);
            Assert.Equal(1, page.Count);
            Assert.Equal("world", page.Buffer[0].Value);
        }
Exemple #30
0
        public async Task Write_WithHtmlString_WritesValueWithoutEncoding()
        {
            // Arrange
            var buffer = new ViewBuffer(new TestViewBufferScope(), string.Empty, pageSize: 32);
            var writer = new ViewBufferTextWriter(buffer, Encoding.UTF8);

            var page = CreatePage(p =>
            {
                p.Write(new HtmlString("Hello world"));
            });
            page.ViewContext.Writer = writer;

            // Act
            await page.ExecuteAsync();

            // Assert
            Assert.Equal("Hello world", HtmlContentUtilities.HtmlContentToString(buffer));
        }
Exemple #31
0
        public async Task WriteToAsync_WritesRazorValuesFromAllBuffers(int valuesToWrite)
        {
            // Arrange
            var buffer = new ViewBuffer(new TestViewBufferScope(), "some-name", pageSize: 4);
            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());
        }
        public String GenTemplate(string relativePath, IDataTable table, List <IDataTable> tables, ModelConfig cfg)
        {
            //var relativePath = @"/Views/Home/Index1.cshtml";
            if (relativePath == null)
            {
                relativePath = "/Template/实体数据/中文名.cs.cshtml";
            }
            var compiler    = _viewCompilerProvider.GetCompiler();// new Microsoft.AspNetCore.Mvc.Razor.Internal.RazorViewCompiler
            var compileTask = compiler.CompileAsync(relativePath);

            var viewDescriptor = compileTask.GetAwaiter().GetResult();

            var viewType = viewDescriptor.Type;

            var newExpression = Expression.New(viewType);
            var pathProperty  = viewType.GetTypeInfo().GetProperty(nameof(IRazorPage.Path));

            // Generate: page.Path = relativePath;
            // Use the normalized path specified from the result.
            var propertyBindExpression     = Expression.Bind(pathProperty, Expression.Constant(viewDescriptor.RelativePath));
            var objectInitializeExpression = Expression.MemberInit(newExpression, propertyBindExpression);
            var pageFactory = Expression
                              .Lambda <Func <IRazorPage> >(objectInitializeExpression)
                              .Compile();

            var page = pageFactory.Invoke();

            var bufferScope  = HttpContext.RequestServices.GetRequiredService <IViewBufferScope>();
            var buffer       = new ViewBuffer(bufferScope, page.Path, ViewBuffer.ViewPageSize);
            var stringWriter = new StringWriter();
            var writer       = new ViewBufferTextWriter(buffer, Encoding.UTF8, _htmlEncoder, stringWriter);

            page.ViewContext = new ViewContext
            {
                Writer   = writer,
                ViewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
            };

            if (page is RazorPageBase rPageBase)
            {
                rPageBase.HtmlEncoder    = _htmlEncoder;
                rPageBase.ViewBag.Config = cfg;
                rPageBase.ViewBag.Table  = table;
                rPageBase.ViewBag.Tables = tables;
                //rPageBase.ViewContext.ViewData.Model = 666;
            }

            var task = page.ExecuteAsync();

            //task.Wait();
            if (task.Exception != null)
            {
                XTrace.WriteLine(task.Exception.ToString());
            }

            writer.Flush();

            var res = HttpUtility.HtmlDecode(stringWriter.ToString());

            return(res);
        }
 public TagHelperScopeInfo(ViewBuffer buffer, HtmlEncoder encoder, TextWriter writer)
 {
     Buffer      = buffer;
     HtmlEncoder = encoder;
     Writer      = writer;
 }
 public void Dispose()
 {
     DiskBuffer?.RemoveService(this);
     ViewBuffer?.RemoveService(this);
 }
        private async Task<IHtmlContent> RenderRazorViewAsync(string path, DisplayContext context)
        {
            var viewEngineResult = _viewEngine.Value.ViewEngines.First().FindView(context.ViewContext, path, isMainPage: false);
            if (viewEngineResult.Success)
            {
                var bufferScope = context.ViewContext.HttpContext.RequestServices.GetRequiredService<IViewBufferScope>();
                var viewBuffer = new ViewBuffer(bufferScope, viewEngineResult.ViewName, ViewBuffer.PartialViewPageSize);
                using (var writer = new ViewBufferTextWriter(viewBuffer, 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 viewBuffer;
                    }
                }
            }

            return null;
        }
Exemple #36
0
        public void MoveTo_ViewBuffer_CanAddToTakenPage()
        {
            // Arrange
            var scope = new TestViewBufferScope();

            var original = new ViewBuffer(scope, "original", pageSize: 4);
            var other = new ViewBuffer(scope, "other", pageSize: 4);

            for (var i = 0; i < 3; i++)
            {
                original.AppendHtml($"original-{i}");
            }

            // More than half full, so we take the page
            for (var i = 0; i < 3; i++)
            {
                other.AppendHtml($"other-{i}");
            }

            var page = other.Pages[0];
            other.MoveTo(original);

            // Act
            original.AppendHtml("after-merge");

            // Assert
            Assert.Empty(other.Pages); // Other is cleared

            Assert.Equal(2, original.Pages.Count);
            Assert.Collection(
                original.Pages[0].Buffer,
                item => Assert.Equal("original-0", item.Value),
                item => Assert.Equal("original-1", item.Value),
                item => Assert.Equal("original-2", item.Value),
                item => Assert.Null(item.Value));
            Assert.Collection(
                original.Pages[1].Buffer,
                item => Assert.Equal("other-0", item.Value),
                item => Assert.Equal("other-1", item.Value),
                item => Assert.Equal("other-2", item.Value),
                item => Assert.Equal("after-merge", item.Value));
        }
Exemple #37
0
        private void Picture_Paint(object sender, PaintEventArgs e)
        {
            ViewBuffer buffer = new ViewBuffer();

            buffer.CreateGraphics(pb.Width, pb.Height);

            Graphics g = buffer.g;

            if (downloaded == false)
            {
                if (selected)
                {
                    SolidBrush basicBrushes = new SolidBrush(Color.FromArgb(170, 234, 202, 233));
                    g.FillRectangle(basicBrushes, 0, 0, Width, Height);
                }
                else if (mouse_enter)
                {
                    SolidBrush basicBrushes = new SolidBrush(Color.FromArgb(100, 234, 202, 233));
                    g.FillRectangle(basicBrushes, 0, 0, Width, Height);
                }
            }
            else
            {
                if (downloading)
                {
                    SolidBrush basicBrushes = new SolidBrush(Color.FromArgb(200, 200, 200, 0));
                    g.FillRectangle(basicBrushes, 0, 0, Width, Height);
                }
                else
                {
                    SolidBrush basicBrushes = new SolidBrush(Color.FromArgb(200, 200, 130, 130));
                    g.FillRectangle(basicBrushes, 0, 0, Width, Height);
                }
            }

            g.SmoothingMode     = SmoothingMode.HighQuality;
            g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;

            float star_position = 2;

            if (downloaded_overlapping)
            {
                g.DrawString("★", new Font(font.FontFamily, 12), Brushes.Orange, new PointF(star_position, 2));
                star_position += 6;
            }

            if (hidden_data)
            {
                g.DrawString("★", new Font(font.FontFamily, 12), Brushes.SkyBlue, new PointF(star_position, 2));
                star_position += 6;
            }

            if (bookmark)
            {
                g.DrawString("★", new Font(font.FontFamily, 12), Brushes.OrangeRed, new PointF(star_position, 2));
            }

            if (callfrom_panel == false)
            {
                callfrom_paint = true;
                Invalidate();
            }
            callfrom_panel = false;

            buffer.Draw(e.Graphics);
            buffer.Dispose();
        }
Exemple #38
0
        public void MoveTo_ViewBuffer_MultiplePages()
        {
            // Arrange
            var scope = new TestViewBufferScope();

            var original = new ViewBuffer(scope, "original", pageSize: 4);
            var other = new ViewBuffer(scope, "other", pageSize: 4);

            for (var i = 0; i < 2; i++)
            {
                original.AppendHtml($"original-{i}");
            }
            
            for (var i = 0; i < 9; i++)
            {
                other.AppendHtml($"other-{i}");
            }

            var pages = new List<ViewBufferPage>(other.Pages);

            // Act
            other.MoveTo(original);

            // Assert
            Assert.Empty(other.Pages); // Other is cleared

            Assert.Equal(4, original.Pages.Count);
            Assert.Collection(
                original.Pages[0].Buffer,
                item => Assert.Equal("original-0", item.Value),
                item => Assert.Equal("original-1", item.Value),
                item => Assert.Null(item.Value),
                item => Assert.Null(item.Value));
            Assert.Collection(
                original.Pages[1].Buffer,
                item => Assert.Equal("other-0", item.Value),
                item => Assert.Equal("other-1", item.Value),
                item => Assert.Equal("other-2", item.Value),
                item => Assert.Equal("other-3", item.Value));
            Assert.Collection(
                original.Pages[2].Buffer,
                item => Assert.Equal("other-4", item.Value),
                item => Assert.Equal("other-5", item.Value),
                item => Assert.Equal("other-6", item.Value),
                item => Assert.Equal("other-7", item.Value));
            Assert.Collection(
                original.Pages[3].Buffer,
                item => Assert.Equal("other-8", item.Value),
                item => Assert.Null(item.Value),
                item => Assert.Null(item.Value),
                item => Assert.Null(item.Value));
        }
Exemple #39
0
        public void MoveTo_FlattensAndClears()
        {
            // Arrange
            var buffer = new ViewBuffer(new TestViewBufferScope(), "some-name", pageSize: 4);

            var nestedItems = new List<object>();
            var nested = new HtmlContentBuilder(nestedItems);
            nested.AppendHtml("Hello");
            buffer.AppendHtml(nested);

            var destinationItems = new List<object>();
            var destination = new HtmlContentBuilder(destinationItems);

            // Act
            buffer.MoveTo(destination);

            // Assert
            Assert.Empty(nestedItems);
            Assert.Empty(buffer.Pages);
            Assert.Equal("Hello", Assert.IsType<HtmlString>(destinationItems[0]).Value);
        }
Exemple #40
0
        public IHtmlContent Render()
        {
            var defaultActions = GetDefaultActions();
            var modeViewPath = _readOnly ? DisplayTemplateViewPath : EditorTemplateViewPath;

            foreach (string viewName in GetViewNames())
            {
                var viewEngineResult = _viewEngine.GetView(_viewContext.ExecutingFilePath, viewName, isMainPage: false);
                if (!viewEngineResult.Success)
                {
                    var fullViewName = modeViewPath + "/" + viewName;
                    viewEngineResult = _viewEngine.FindView(_viewContext, fullViewName, isMainPage: false);
                }

                if (viewEngineResult.Success)
                {
                    var viewBuffer = new ViewBuffer(_bufferScope, viewName, ViewBuffer.PartialViewPageSize);
                    using (var writer = new ViewBufferTextWriter(viewBuffer, _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 viewBuffer;
                        }
                    }
                }

                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 #41
0
        public void MoveTo_ViewBuffer_TakesPage_IfOriginalIsEmpty()
        {
            // Arrange
            var scope = new TestViewBufferScope();

            var original = new ViewBuffer(scope, "original", pageSize: 4);
            var other = new ViewBuffer(scope, "other", pageSize: 4);

            other.AppendHtml("Hi");

            var page = other.Pages[0];

            // Act
            other.MoveTo(original);

            // Assert
            Assert.Empty(other.Pages); // Page was taken
            Assert.Same(page, Assert.Single(original.Pages));
        }
Exemple #42
0
        public async Task WriteToAsync_WritesRazorValues_ToTextWriter()
        {
            // Arrange
            var buffer = new ViewBuffer(new TestViewBufferScope(), "some-name", pageSize: 128);
            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("HtmlEncode[[Hello]] world 123", writer.ToString());
        }
Exemple #43
0
 public HtmlRenderingContext(ViewBuffer viewBuffer)
 {
     HtmlContentBuilder = viewBuffer;
 }