Adding support for Render Section
Initial draft for DefineSection \ RenderSection. This change is based on changes to the Razor parser to enable Razor to generate HelperResults for section instead of void delegates.
This commit is contained in:
parent
75dae948b2
commit
df9d5c4875
|
|
@ -12,6 +12,29 @@
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@section header {
|
||||||
|
<style type="text/css">
|
||||||
|
#qux {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#qux.foo {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
}
|
||||||
|
|
||||||
|
@section footer {
|
||||||
|
<script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.0.min.js"></script>
|
||||||
|
<script>
|
||||||
|
$(function () {
|
||||||
|
$("#qux").fadeIn(3000, function () {
|
||||||
|
$(this).addClass("foo")
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
}
|
||||||
|
|
||||||
@functions {
|
@functions {
|
||||||
public async Task<string> AsyncValueRetrieval()
|
public async Task<string> AsyncValueRetrieval()
|
||||||
{
|
{
|
||||||
|
|
@ -32,7 +55,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h3 title="@Model.Name" class="@nullValue">Hello @Model.Name! Happy @Model.Age birthday.</h3>
|
<h3 title="@Model.Name" class="@nullValue">Hello @Model.Name! Happy @Model.Age birthday.</h3>
|
||||||
<h3>This value was retrieved asynchronously: @(await AsyncValueRetrieval())</h3>
|
<h3 id ="qux">This value was retrieved asynchronously: @(await AsyncValueRetrieval())</h3>
|
||||||
<h3>Partial Async: @await Html.PartialAsync("HelloWorldPartial", Model)</h3>
|
<h3>Partial Async: @await Html.PartialAsync("HelloWorldPartial", Model)</h3>
|
||||||
<h3>Render Partial Async (Custom model): @{ await RenderHelloWorldPartial(new User()
|
<h3>Render Partial Async (Custom model): @{ await RenderHelloWorldPartial(new User()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>@ViewBag.Title - My ASP.NET Application</title>
|
<title>@ViewBag.Title - My ASP.NET Application</title>
|
||||||
<link rel="stylesheet" href="~/content/bootstrap.min.css" />
|
<link rel="stylesheet" href="~/content/bootstrap.min.css" />
|
||||||
|
@RenderSection("header")
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="navbar navbar-inverse navbar-fixed-top">
|
<div class="navbar navbar-inverse navbar-fixed-top">
|
||||||
|
|
@ -36,5 +37,6 @@
|
||||||
<p>© @DateTime.Now.Year - My ASP.NET Application</p>
|
<p>© @DateTime.Now.Year - My ASP.NET Application</p>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
@RenderSection("footer")
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,38 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
return GetString("RenderBodyCannotBeCalled");
|
return GetString("RenderBodyCannotBeCalled");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Section '{0}' is already defined.
|
||||||
|
/// </summary>
|
||||||
|
internal static string SectionAlreadyDefined
|
||||||
|
{
|
||||||
|
get { return GetString("SectionAlreadyDefined"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Section '{0}' is already defined.
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatSectionAlreadyDefined(object p0)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.CurrentCulture, GetString("SectionAlreadyDefined"), p0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Section '{0}' is not defined
|
||||||
|
/// </summary>
|
||||||
|
internal static string SectionNotDefined
|
||||||
|
{
|
||||||
|
get { return GetString("SectionNotDefined"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Section '{0}' is not defined
|
||||||
|
/// </summary>
|
||||||
|
internal static string FormatSectionNotDefined(object p0)
|
||||||
|
{
|
||||||
|
return string.Format(CultureInfo.CurrentCulture, GetString("SectionNotDefined"), p0);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The partial view '{0}' was not found. The following locations were searched:{1}
|
/// The partial view '{0}' was not found. The following locations were searched:{1}
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
@ -36,8 +37,13 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
|
|
||||||
private string BodyContent { get; set; }
|
private string BodyContent { get; set; }
|
||||||
|
|
||||||
|
private Dictionary<string, HelperResult> SectionWriters { get; set; }
|
||||||
|
|
||||||
|
private Dictionary<string, HelperResult> PreviousSectionWriters { get; set; }
|
||||||
|
|
||||||
public virtual async Task RenderAsync([NotNull] ViewContext context)
|
public virtual async Task RenderAsync([NotNull] ViewContext context)
|
||||||
{
|
{
|
||||||
|
SectionWriters = new Dictionary<string, HelperResult>(StringComparer.OrdinalIgnoreCase);
|
||||||
Context = context;
|
Context = context;
|
||||||
|
|
||||||
var contentBuilder = new StringBuilder(1024);
|
var contentBuilder = new StringBuilder(1024);
|
||||||
|
|
@ -82,12 +88,22 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
throw new InvalidOperationException(message);
|
throw new InvalidOperationException(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
layoutView.PreviousSectionWriters = SectionWriters;
|
||||||
layoutView.BodyContent = bodyContent;
|
layoutView.BodyContent = bodyContent;
|
||||||
await layoutView.RenderAsync(context);
|
await layoutView.RenderAsync(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Task ExecuteAsync();
|
public abstract Task ExecuteAsync();
|
||||||
|
|
||||||
|
public void DefineSection(string name, HelperResult action)
|
||||||
|
{
|
||||||
|
if (SectionWriters.ContainsKey(name))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(Resources.FormatSectionAlreadyDefined(name));
|
||||||
|
}
|
||||||
|
SectionWriters[name] = action;
|
||||||
|
}
|
||||||
|
|
||||||
public virtual void Write(object value)
|
public virtual void Write(object value)
|
||||||
{
|
{
|
||||||
WriteTo(Output, value);
|
WriteTo(Output, value);
|
||||||
|
|
@ -242,5 +258,29 @@ namespace Microsoft.AspNet.Mvc.Razor
|
||||||
}
|
}
|
||||||
return new HtmlString(BodyContent);
|
return new HtmlString(BodyContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public HelperResult RenderSection(string name)
|
||||||
|
{
|
||||||
|
return RenderSection(name, required: false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HelperResult RenderSection(string name, bool required)
|
||||||
|
{
|
||||||
|
HelperResult action;
|
||||||
|
if (PreviousSectionWriters.TryGetValue(name, out action))
|
||||||
|
{
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
else if (required)
|
||||||
|
{
|
||||||
|
// If the section is not found, and it is not optional, throw an error.
|
||||||
|
throw new InvalidOperationException(Resources.FormatSectionNotDefined(name));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If the section is optional and not found, then don't do anything.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,12 @@
|
||||||
<data name="RenderBodyCannotBeCalled" xml:space="preserve">
|
<data name="RenderBodyCannotBeCalled" xml:space="preserve">
|
||||||
<value>RenderBody can only be called from a layout page.</value>
|
<value>RenderBody can only be called from a layout page.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="SectionAlreadyDefined" xml:space="preserve">
|
||||||
|
<value>Section '{0}' is already defined.</value>
|
||||||
|
</data>
|
||||||
|
<data name="SectionNotDefined" xml:space="preserve">
|
||||||
|
<value>Section '{0}' is not defined</value>
|
||||||
|
</data>
|
||||||
<data name="ViewEngine_PartialViewNotFound" xml:space="preserve">
|
<data name="ViewEngine_PartialViewNotFound" xml:space="preserve">
|
||||||
<value>The partial view '{0}' was not found. The following locations were searched:{1}</value>
|
<value>The partial view '{0}' was not found. The following locations were searched:{1}</value>
|
||||||
</data>
|
</data>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue