diff --git a/samples/MvcSandbox/Pages/Index.cshtml b/samples/MvcSandbox/Pages/Index.cshtml
index bde7d9957d..3c565a3b59 100644
--- a/samples/MvcSandbox/Pages/Index.cshtml
+++ b/samples/MvcSandbox/Pages/Index.cshtml
@@ -1,5 +1,9 @@
@page
@model TestModel
+@{
+
+ ViewData["Title"] = "Hello from pages";
+}
@functions {
diff --git a/samples/MvcSandbox/Pages/_PageStart.cshtml b/samples/MvcSandbox/Pages/_PageStart.cshtml
new file mode 100644
index 0000000000..26214bbe6c
--- /dev/null
+++ b/samples/MvcSandbox/Pages/_PageStart.cshtml
@@ -0,0 +1 @@
+@{ Layout = "_Layout";}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.Razor/RazorPage.cs b/src/Microsoft.AspNetCore.Mvc.Razor/RazorPage.cs
index 87888c486a..bab23fd534 100644
--- a/src/Microsoft.AspNetCore.Mvc.Razor/RazorPage.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Razor/RazorPage.cs
@@ -4,21 +4,14 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
-using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Html;
-using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Razor.Internal;
using Microsoft.AspNetCore.Mvc.Rendering;
-using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
-using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
-using Microsoft.AspNetCore.Razor.TagHelpers;
-using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Mvc.Razor
{
@@ -28,34 +21,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor
public abstract class RazorPage : RazorPageBase, IRazorPage
{
private readonly HashSet _renderedSections = new HashSet(StringComparer.OrdinalIgnoreCase);
- private readonly Stack _tagHelperScopes = new Stack();
- private IUrlHelper _urlHelper;
- private ITagHelperFactory _tagHelperFactory;
private bool _renderedBody;
- private StringWriter _valueBuffer;
- private IViewBufferScope _bufferScope;
private bool _ignoreBody;
private HashSet _ignoredSections;
- private TextWriter _pageWriter;
-
- public RazorPage()
- {
- SectionWriters = new Dictionary(StringComparer.OrdinalIgnoreCase);
- }
-
- ///
- /// An representing the current request execution.
- ///
- public HttpContext Context => ViewContext?.HttpContext;
-
- ///
- public string Path { get; set; }
-
- ///
- public ViewContext ViewContext { get; set; }
-
- ///
- public string Layout { get; set; }
///
/// Gets the to use when this
@@ -70,33 +38,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor
[RazorInject]
public DiagnosticSource DiagnosticSource { get; set; }
- ///
- /// Gets the that the page is writing output to.
- ///
- public virtual TextWriter Output
- {
- get
- {
- if (ViewContext == null)
- {
- var message = Resources.FormatViewContextMustBeSet("ViewContext", "Output");
- throw new InvalidOperationException(message);
- }
-
- return ViewContext.Writer;
- }
- }
-
///
/// Gets the of the current logged in user.
///
public virtual ClaimsPrincipal User => Context?.User;
- ///
- /// Gets the dynamic view data dictionary.
- ///
- public dynamic ViewBag => ViewContext?.ViewBag;
-
///
/// Gets the from the .
///
@@ -106,47 +52,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor
///
public IHtmlContent BodyContent { get; set; }
- ///
- public bool IsLayoutBeingRendered { get; set; }
-
///
public IDictionary PreviousSectionWriters { get; set; }
- ///
- public IDictionary SectionWriters { get; }
-
- protected override TextWriter Writer => Output;
-
protected override HtmlEncoder Encoder => HtmlEncoder;
- private ITagHelperFactory TagHelperFactory
- {
- get
- {
- if (_tagHelperFactory == null)
- {
- var services = ViewContext.HttpContext.RequestServices;
- _tagHelperFactory = services.GetRequiredService();
- }
-
- return _tagHelperFactory;
- }
- }
-
- private IViewBufferScope BufferScope
- {
- get
- {
- if (_bufferScope == null)
- {
- var services = ViewContext.HttpContext.RequestServices;
- _bufferScope = services.GetRequiredService();
- }
-
- return _bufferScope;
- }
- }
-
///
/// Format an error message about using an indexer when the tag helper property is null.
///
@@ -165,142 +75,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor
propertyName);
}
- ///
- /// Creates and activates a .
- ///
- /// A type.
- /// The activated .
- ///
- /// must have a parameterless constructor.
- ///
- public TTagHelper CreateTagHelper() where TTagHelper : ITagHelper
- {
- return TagHelperFactory.CreateTagHelper(ViewContext);
- }
-
- ///
- /// Starts a new writing scope and optionally overrides within that scope.
- ///
- ///
- /// The to use when this handles
- /// non- C# expressions. If null, does not change .
- ///
- ///
- /// All writes to the or after calling this method will
- /// be buffered until is called.
- ///
- public void StartTagHelperWritingScope(HtmlEncoder encoder)
- {
- var buffer = new ViewBuffer(BufferScope, Path, ViewBuffer.TagHelperPageSize);
- _tagHelperScopes.Push(new TagHelperScopeInfo(buffer, HtmlEncoder, ViewContext.Writer));
-
- // If passed an HtmlEncoder, override the property.
- if (encoder != null)
- {
- HtmlEncoder = encoder;
- }
-
- // We need to replace the ViewContext's Writer to ensure that all content (including content written
- // from HTML helpers) is redirected.
- ViewContext.Writer = new ViewBufferTextWriter(buffer, ViewContext.Writer.Encoding);
- }
-
- ///
- /// Ends the current writing scope that was started by calling .
- ///
- /// The buffered .
- public TagHelperContent EndTagHelperWritingScope()
- {
- if (_tagHelperScopes.Count == 0)
- {
- throw new InvalidOperationException(Resources.RazorPage_ThereIsNoActiveWritingScopeToEnd);
- }
-
- var scopeInfo = _tagHelperScopes.Pop();
-
- // Get the content written during the current scope.
- var tagHelperContent = new DefaultTagHelperContent();
- tagHelperContent.AppendHtml(scopeInfo.Buffer);
-
- // Restore previous scope.
- HtmlEncoder = scopeInfo.Encoder;
- ViewContext.Writer = scopeInfo.Writer;
-
- return tagHelperContent;
- }
-
- ///
- /// Starts a new scope for writing attribute values.
- ///
- ///
- /// All writes to the or after calling this method will
- /// be buffered until is called.
- /// The content will be buffered using a shared within this
- /// Nesting of and method calls
- /// is not supported.
- ///
- public void BeginWriteTagHelperAttribute()
- {
- if (_pageWriter != null)
- {
- throw new InvalidOperationException(Resources.RazorPage_NestingAttributeWritingScopesNotSupported);
- }
-
- _pageWriter = ViewContext.Writer;
-
- if (_valueBuffer == null)
- {
- _valueBuffer = new StringWriter();
- }
-
- // We need to replace the ViewContext's Writer to ensure that all content (including content written
- // from HTML helpers) is redirected.
- ViewContext.Writer = _valueBuffer;
-
- }
-
- ///
- /// Ends the current writing scope that was started by calling .
- ///
- /// The content buffered by the shared of this .
- ///
- /// This method assumes that there will be no nesting of
- /// and method calls.
- ///
- public string EndWriteTagHelperAttribute()
- {
- if (_pageWriter == null)
- {
- throw new InvalidOperationException(Resources.RazorPage_ThereIsNoActiveWritingScopeToEnd);
- }
-
- var content = _valueBuffer.ToString();
- _valueBuffer.GetStringBuilder().Clear();
-
- // Restore previous writer.
- ViewContext.Writer = _pageWriter;
- _pageWriter = null;
-
- return content;
- }
-
- public override string Href(string contentPath)
- {
- if (contentPath == null)
- {
- throw new ArgumentNullException(nameof(contentPath));
- }
-
- if (_urlHelper == null)
- {
- var services = Context.RequestServices;
- var factory = services.GetRequiredService();
- _urlHelper = factory.GetUrlHelper(ViewContext);
- }
-
- return _urlHelper.Content(contentPath);
- }
-
///
/// In a Razor layout page, renders the portion of a content page that is not within a named section.
///
@@ -371,7 +145,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
///
/// The name of the section to render.
/// An empty .
- /// The method writes to the and the value returned is a token
+ /// The method writes to the and the value returned is a token
/// value that allows the Write (produced due to @RenderSection(..)) to succeed. However the
/// value does not represent the rendered content.
public HtmlString RenderSection(string name)
@@ -390,7 +164,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
/// The section to render.
/// Indicates if this section must be rendered.
/// An empty .
- /// The method writes to the and the value returned is a token
+ /// The method writes to the and the value returned is a token
/// value that allows the Write (produced due to @RenderSection(..)) to succeed. However the
/// value does not represent the rendered content.
public HtmlString RenderSection(string name, bool required)
@@ -413,7 +187,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
///
/// A that on completion returns an empty .
///
- /// The method writes to the and the value returned is a token
+ /// The method writes to the and the value returned is a token
/// value that allows the Write (produced due to @RenderSection(..)) to succeed. However the
/// value does not represent the rendered content.
public Task RenderSectionAsync(string name)
@@ -435,7 +209,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
///
/// A that on completion returns an empty .
///
- /// The method writes to the and the value returned is a token
+ /// The method writes to the and the value returned is a token
/// value that allows the Write (produced due to @RenderSection(..)) to succeed. However the
/// value does not represent the rendered content.
/// if is true and the section
@@ -514,40 +288,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor
_ignoredSections.Add(sectionName);
}
- ///
- /// Invokes on and
- /// on the response stream, writing out any buffered content to the .
- ///
- /// A that represents the asynchronous flush operation and on
- /// completion returns an empty .
- /// The value returned is a token value that allows FlushAsync to work directly in an HTML
- /// section. However the value does not represent the rendered content.
- /// This method also writes out headers, so any modifications to headers must be done before
- /// is called. For example, call to send
- /// antiforgery cookie token and X-Frame-Options header to client before this method flushes headers out.
- ///
- public async Task FlushAsync()
- {
- // If there are active scopes, then we should throw. Cannot flush content that has the potential to change.
- if (_tagHelperScopes.Count > 0)
- {
- throw new InvalidOperationException(
- Resources.FormatRazorPage_CannotFlushWhileInAWritingScope(nameof(FlushAsync), Path));
- }
-
- // Calls to Flush are allowed if the page does not specify a Layout or if it is executing a section in the
- // Layout.
- if (!IsLayoutBeingRendered && !string.IsNullOrEmpty(Layout))
- {
- var message = Resources.FormatLayoutCannotBeRendered(Path, nameof(FlushAsync));
- throw new InvalidOperationException(message);
- }
-
- await Writer.FlushAsync();
- await Context.Response.Body.FlushAsync();
- return HtmlString.Empty;
- }
-
///
public void EnsureRenderedBodyOrSections()
{
@@ -619,20 +359,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor
}
}
- ///
- /// Sets antiforgery cookie and X-Frame-Options header on the response.
- ///
- /// An empty .
- /// Call this method to send antiforgery cookie token and X-Frame-Options header to client
- /// before flushes the headers.
- public virtual HtmlString SetAntiforgeryCookieAndHeader()
- {
- var antiforgery = Context.RequestServices.GetRequiredService();
- antiforgery.SetCookieTokenAndHeader(Context);
-
- return HtmlString.Empty;
- }
-
private void EnsureMethodCanBeInvoked(string methodName)
{
if (PreviousSectionWriters == null)
@@ -640,21 +366,5 @@ namespace Microsoft.AspNetCore.Mvc.Razor
throw new InvalidOperationException(Resources.FormatRazorPage_MethodCannotBeCalled(methodName, Path));
}
}
-
- private struct TagHelperScopeInfo
- {
- public TagHelperScopeInfo(ViewBuffer buffer, HtmlEncoder encoder, TextWriter writer)
- {
- Buffer = buffer;
- Encoder = encoder;
- Writer = writer;
- }
-
- public ViewBuffer Buffer { get; }
-
- public HtmlEncoder Encoder { get; }
-
- public TextWriter Writer { get; }
- }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.Razor/RazorPageBase.cs b/src/Microsoft.AspNetCore.Mvc.Razor/RazorPageBase.cs
index 05f3e8ca16..9f852567a7 100644
--- a/src/Microsoft.AspNetCore.Mvc.Razor/RazorPageBase.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Razor/RazorPageBase.cs
@@ -2,14 +2,20 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
+using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
+using Microsoft.AspNetCore.Antiforgery;
using Microsoft.AspNetCore.Html;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc.Rendering;
+using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal;
using Microsoft.AspNetCore.Razor.Runtime.TagHelpers;
using Microsoft.AspNetCore.Razor.TagHelpers;
+using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Mvc.Razor
{
@@ -18,26 +24,245 @@ namespace Microsoft.AspNetCore.Mvc.Razor
///
public abstract class RazorPageBase
{
+ private StringWriter _valueBuffer;
+ private ITagHelperFactory _tagHelperFactory;
+ private IViewBufferScope _bufferScope;
+ private TextWriter _pageWriter;
private AttributeInfo _attributeInfo;
private TagHelperAttributeInfo _tagHelperAttributeInfo;
- private StringWriter _valueBuffer;
+ private IUrlHelper _urlHelper;
+
+ public ViewContext ViewContext { get; set; }
+
+ public string Layout { get; set; }
+
+ ///
+ /// An representing the current request execution.
+ ///
+ public HttpContext Context => ViewContext?.HttpContext;
///
/// Gets the that the page is writing output to.
///
- protected abstract TextWriter Writer { get; }
+ ///
+ /// Gets the that the page is writing output to.
+ ///
+ public virtual TextWriter Output
+ {
+ get
+ {
+ if (ViewContext == null)
+ {
+ var message = Resources.FormatViewContextMustBeSet("ViewContext", "Output");
+ throw new InvalidOperationException(message);
+ }
- protected abstract HtmlEncoder Encoder { get; }
+ return ViewContext.Writer;
+ }
+ }
+
+ ///
+ public string Path { get; set; }
+
+ ///
+ public IDictionary SectionWriters { get; } =
+ new Dictionary(StringComparer.OrdinalIgnoreCase);
+
+ ///
+ /// Gets the dynamic view data dictionary.
+ ///
+ public dynamic ViewBag => ViewContext?.ViewBag;
+
+ public bool IsLayoutBeingRendered { get; set; }
+
+ protected virtual HtmlEncoder Encoder { get; set; }
+
+ protected Stack TagHelperScopes { get; } = new Stack();
+
+ private ITagHelperFactory TagHelperFactory
+ {
+ get
+ {
+ if (_tagHelperFactory == null)
+ {
+ var services = ViewContext.HttpContext.RequestServices;
+ _tagHelperFactory = services.GetRequiredService();
+ }
+
+ return _tagHelperFactory;
+ }
+ }
+
+ private IViewBufferScope BufferScope
+ {
+ get
+ {
+ if (_bufferScope == null)
+ {
+ var services = ViewContext.HttpContext.RequestServices;
+ _bufferScope = services.GetRequiredService();
+ }
+
+ return _bufferScope;
+ }
+ }
public abstract Task ExecuteAsync();
///
- /// Writes the specified with HTML encoding to .
+ /// Creates and activates a .
+ ///
+ /// A type.
+ /// The activated .
+ ///
+ /// must have a parameterless constructor.
+ ///
+ public TTagHelper CreateTagHelper() where TTagHelper : ITagHelper
+ {
+ return TagHelperFactory.CreateTagHelper(ViewContext);
+ }
+
+ ///
+ /// Starts a new writing scope and optionally overrides within that scope.
+ ///
+ ///
+ /// The to use when this handles
+ /// non- C# expressions. If null, does not change .
+ ///
+ ///
+ /// All writes to the or after calling this method will
+ /// be buffered until is called.
+ ///
+ public void StartTagHelperWritingScope(HtmlEncoder encoder)
+ {
+ var buffer = new ViewBuffer(BufferScope, Path, ViewBuffer.TagHelperPageSize);
+ TagHelperScopes.Push(new TagHelperScopeInfo(buffer, Encoder, ViewContext.Writer));
+
+ // If passed an HtmlEncoder, override the property.
+ if (encoder != null)
+ {
+ Encoder = encoder;
+ }
+
+ // We need to replace the ViewContext's Writer to ensure that all content (including content written
+ // from HTML helpers) is redirected.
+ ViewContext.Writer = new ViewBufferTextWriter(buffer, ViewContext.Writer.Encoding);
+ }
+
+ ///
+ /// Ends the current writing scope that was started by calling .
+ ///
+ /// The buffered .
+ public TagHelperContent EndTagHelperWritingScope()
+ {
+ var scopeInfo = TagHelperScopes.Pop();
+
+ // Get the content written during the current scope.
+ var tagHelperContent = new DefaultTagHelperContent();
+ tagHelperContent.AppendHtml(scopeInfo.Buffer);
+
+ // Restore previous scope.
+ Encoder = scopeInfo.Encoder;
+ ViewContext.Writer = scopeInfo.Writer;
+
+ return tagHelperContent;
+ }
+
+ ///
+ /// Starts a new scope for writing attribute values.
+ ///
+ ///
+ /// All writes to the or after calling this method will
+ /// be buffered until is called.
+ /// The content will be buffered using a shared within this
+ /// Nesting of and method calls
+ /// is not supported.
+ ///
+ public void BeginWriteTagHelperAttribute()
+ {
+ _pageWriter = ViewContext.Writer;
+
+ if (_valueBuffer == null)
+ {
+ _valueBuffer = new StringWriter();
+ }
+
+ // We need to replace the ViewContext's Writer to ensure that all content (including content written
+ // from HTML helpers) is redirected.
+ ViewContext.Writer = _valueBuffer;
+
+ }
+
+ ///
+ /// Ends the current writing scope that was started by calling .
+ ///
+ /// The content buffered by the shared of this .
+ ///
+ /// This method assumes that there will be no nesting of
+ /// and method calls.
+ ///
+ public string EndWriteTagHelperAttribute()
+ {
+ var content = _valueBuffer.ToString();
+ _valueBuffer.GetStringBuilder().Clear();
+
+ // Restore previous writer.
+ ViewContext.Writer = _pageWriter;
+ _pageWriter = null;
+
+ return content;
+ }
+
+ public virtual string Href(string contentPath)
+ {
+ if (contentPath == null)
+ {
+ throw new ArgumentNullException(nameof(contentPath));
+ }
+
+ if (_urlHelper == null)
+ {
+ var services = Context.RequestServices;
+ var factory = services.GetRequiredService();
+ _urlHelper = factory.GetUrlHelper(ViewContext);
+ }
+
+ return _urlHelper.Content(contentPath);
+ }
+
+ ///
+ /// Creates a named content section in the page that can be invoked in a Layout page using
+ /// RenderSection or RenderSectionAsync
+ ///
+ /// The name of the section to create.
+ /// The to execute when rendering the section.
+ public virtual void DefineSection(string name, RenderAsyncDelegate section)
+ {
+ if (name == null)
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
+
+ if (section == null)
+ {
+ throw new ArgumentNullException(nameof(section));
+ }
+
+ if (SectionWriters.ContainsKey(name))
+ {
+ throw new InvalidOperationException(Resources.FormatSectionAlreadyDefined(name));
+ }
+ SectionWriters[name] = section;
+ }
+
+
+ ///
+ /// Writes the specified with HTML encoding to .
///
/// The to write.
public virtual void Write(object value)
{
- WriteTo(Writer, value);
+ WriteTo(Output, value);
}
///
@@ -149,12 +374,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor
}
///
- /// Writes the specified without HTML encoding to .
+ /// Writes the specified without HTML encoding to .
///
/// The to write.
public virtual void WriteLiteral(object value)
{
- WriteLiteralTo(Writer, value);
+ WriteLiteralTo(Output, value);
}
///
@@ -176,7 +401,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
}
///
- /// Writes the specified without HTML encoding to .
+ /// Writes the specified without HTML encoding to .
///
/// The instance to write to.
/// The to write.
@@ -201,7 +426,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
int suffixOffset,
int attributeValuesCount)
{
- BeginWriteAttributeTo(Writer, name, prefix, prefixOffset, suffix, suffixOffset, attributeValuesCount);
+ BeginWriteAttributeTo(Output, name, prefix, prefixOffset, suffix, suffixOffset, attributeValuesCount);
}
public virtual void BeginWriteAttributeTo(
@@ -246,7 +471,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
int valueLength,
bool isLiteral)
{
- WriteAttributeValueTo(Writer, prefix, prefixOffset, value, valueOffset, valueLength, isLiteral);
+ WriteAttributeValueTo(Output, prefix, prefixOffset, value, valueOffset, valueLength, isLiteral);
}
public void WriteAttributeValueTo(
@@ -297,7 +522,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
public virtual void EndWriteAttribute()
{
- EndWriteAttributeTo(Writer);
+ EndWriteAttributeTo(Output);
}
public virtual void EndWriteAttributeTo(TextWriter writer)
@@ -392,7 +617,54 @@ namespace Microsoft.AspNetCore.Mvc.Razor
}
}
- public abstract string Href(string contentPath);
+ ///
+ /// Invokes on and
+ /// on the response stream, writing out any buffered content to the .
+ ///
+ /// A that represents the asynchronous flush operation and on
+ /// completion returns an empty .
+ /// The value returned is a token value that allows FlushAsync to work directly in an HTML
+ /// section. However the value does not represent the rendered content.
+ /// This method also writes out headers, so any modifications to headers must be done before
+ /// is called. For example, call to send
+ /// antiforgery cookie token and X-Frame-Options header to client before this method flushes headers out.
+ ///
+
+ public virtual async Task FlushAsync()
+ {
+ // If there are active scopes, then we should throw. Cannot flush content that has the potential to change.
+ if (TagHelperScopes.Count > 0)
+ {
+ throw new InvalidOperationException(
+ "Resources.FormatRazorPage_CannotFlushWhileInAWritingScope(nameof(FlushAsync), Path))");
+ }
+
+ // Calls to Flush are allowed if the page does not specify a Layout or if it is executing a section in the
+ // Layout.
+ if (!IsLayoutBeingRendered && !string.IsNullOrEmpty(Layout))
+ {
+ var message = Resources.FormatLayoutCannotBeRendered(Path, nameof(FlushAsync));
+ throw new InvalidOperationException(message);
+ }
+
+ await Output.FlushAsync();
+ await Context.Response.Body.FlushAsync();
+ return HtmlString.Empty;
+ }
+
+ ///
+ /// Sets antiforgery cookie and X-Frame-Options header on the response.
+ ///
+ /// An empty .
+ /// Call this method to send antiforgery cookie token and X-Frame-Options header to client
+ /// before flushes the headers.
+ public virtual HtmlString SetAntiforgeryCookieAndHeader()
+ {
+ var antiforgery = Context.RequestServices.GetRequiredService();
+ antiforgery.SetCookieTokenAndHeader(Context);
+
+ return HtmlString.Empty;
+ }
private void WriteUnprefixedAttributeValueTo(TextWriter writer, object value, bool isLiteral)
{
@@ -424,13 +696,6 @@ namespace Microsoft.AspNetCore.Mvc.Razor
EndContext();
}
- ///
- /// Creates a named content section in the page.
- ///
- /// The name of the section to create.
- /// The to execute when rendering the section.
- public abstract void DefineSection(string name, RenderAsyncDelegate section);
-
public abstract void BeginContext(int position, int length, bool isLiteral);
public abstract void EndContext();
@@ -510,5 +775,21 @@ namespace Microsoft.AspNetCore.Mvc.Razor
public bool Suppressed { get; set; }
}
+
+ protected struct TagHelperScopeInfo
+ {
+ public TagHelperScopeInfo(ViewBuffer buffer, HtmlEncoder encoder, TextWriter writer)
+ {
+ Buffer = buffer;
+ Encoder = encoder;
+ Writer = writer;
+ }
+
+ public ViewBuffer Buffer { get; }
+
+ public HtmlEncoder Encoder { get; }
+
+ public TextWriter Writer { get; }
+ }
}
}
\ No newline at end of file
diff --git a/src/Microsoft.AspNetCore.Mvc.RazorPages/Infrastructure/PageResultExecutor.cs b/src/Microsoft.AspNetCore.Mvc.RazorPages/Infrastructure/PageResultExecutor.cs
index 64d088f2a9..02d07b5410 100644
--- a/src/Microsoft.AspNetCore.Mvc.RazorPages/Infrastructure/PageResultExecutor.cs
+++ b/src/Microsoft.AspNetCore.Mvc.RazorPages/Infrastructure/PageResultExecutor.cs
@@ -40,8 +40,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
: base(writerFactory, compositeViewEngine, diagnosticSource)
{
_razorViewEngine = razorViewEngine;
- _razorPageActivator = new PassThruRazorPageActivator(razorPageActivator);
_htmlEncoder = htmlEncoder;
+ _razorPageActivator = new PassThruRazorPageActivator(razorPageActivator);
}
///
diff --git a/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/PassThruRazorPageActivator.cs b/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/PassThruRazorPageActivator.cs
index 3da7fd9897..3305b07f62 100644
--- a/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/PassThruRazorPageActivator.cs
+++ b/src/Microsoft.AspNetCore.Mvc.RazorPages/Internal/PassThruRazorPageActivator.cs
@@ -1,8 +1,10 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.Rendering;
+using Microsoft.AspNetCore.Mvc.ViewFeatures;
namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
{
@@ -20,10 +22,16 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
var razorView = (RazorView)context.View;
if (ReferenceEquals(page, razorView.RazorPage))
{
- return;
- }
+ var pageContext = (PageContext)context;
+ var vddType = typeof(ViewDataDictionary<>);
+ vddType = vddType.MakeGenericType(pageContext.ActionDescriptor.ModelTypeInfo.AsType());
- _pageActivator.Activate(page, context);
+ context.ViewData = (ViewDataDictionary)Activator.CreateInstance(vddType, context.ViewData);
+ }
+ else
+ {
+ _pageActivator.Activate(page, context);
+ }
}
}
}
diff --git a/src/Microsoft.AspNetCore.Mvc.RazorPages/Page.cs b/src/Microsoft.AspNetCore.Mvc.RazorPages/Page.cs
index 5514035d79..02d3e43077 100644
--- a/src/Microsoft.AspNetCore.Mvc.RazorPages/Page.cs
+++ b/src/Microsoft.AspNetCore.Mvc.RazorPages/Page.cs
@@ -4,14 +4,11 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.IO;
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.Razor.Internal;
using Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure;
-using Microsoft.AspNetCore.Mvc.Rendering;
-using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Mvc.RazorPages
@@ -27,29 +24,14 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
///
public IHtmlContent BodyContent { get; set; }
- ///
- public bool IsLayoutBeingRendered { get; set; }
-
- ///
- public string Layout { get; set; }
-
- ///
- public string Path { get; set; }
-
///
public IDictionary PreviousSectionWriters { get; set; }
- ///
- public IDictionary SectionWriters { get; }
-
///
/// The .
///
public PageContext PageContext { get; set; }
- ///
- public ViewContext ViewContext { get; set; }
-
///
/// Gets or sets a instance used to instrument the page execution.
///
@@ -61,7 +43,11 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
/// handles non- C# expressions.
///
[RazorInject]
- public HtmlEncoder HtmlEncoder { get; set; }
+ public HtmlEncoder HtmlEncoder
+ {
+ get { return Encoder; }
+ set { Encoder = value; }
+ }
public PageArgumentBinder Binder
{
@@ -86,10 +72,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
}
}
- protected override HtmlEncoder Encoder => HtmlEncoder;
-
- protected override TextWriter Writer => ViewContext.Writer;
-
///
public void EnsureRenderedBodyOrSections()
{
@@ -131,26 +113,5 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages
}
}
- public override string Href(string contentPath)
- {
- if (contentPath == null)
- {
- throw new ArgumentNullException(nameof(contentPath));
- }
-
- if (_urlHelper == null)
- {
- var services = ViewContext.HttpContext.RequestServices;
- var factory = services.GetRequiredService();
- _urlHelper = factory.GetUrlHelper(ViewContext);
- }
-
- return _urlHelper.Content(contentPath);
- }
-
- public override void DefineSection(string name, RenderAsyncDelegate section)
- {
-
- }
}
}