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:
Pranav K 2014-03-31 12:37:17 -07:00
parent 75dae948b2
commit df9d5c4875
5 changed files with 104 additions and 1 deletions

View File

@ -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 {
public async Task<string> AsyncValueRetrieval()
{
@ -32,7 +55,7 @@
</div>
<div class="row">
<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>Render Partial Async (Custom model): @{ await RenderHelloWorldPartial(new User()
{

View File

@ -5,6 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>@ViewBag.Title - My ASP.NET Application</title>
<link rel="stylesheet" href="~/content/bootstrap.min.css" />
@RenderSection("header")
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
@ -36,5 +37,6 @@
<p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>
@RenderSection("footer")
</body>
</html>

View File

@ -106,6 +106,38 @@ namespace Microsoft.AspNet.Mvc.Razor
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>
/// The partial view '{0}' was not found. The following locations were searched:{1}
/// </summary>

View File

@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
@ -36,8 +37,13 @@ namespace Microsoft.AspNet.Mvc.Razor
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)
{
SectionWriters = new Dictionary<string, HelperResult>(StringComparer.OrdinalIgnoreCase);
Context = context;
var contentBuilder = new StringBuilder(1024);
@ -82,12 +88,22 @@ namespace Microsoft.AspNet.Mvc.Razor
throw new InvalidOperationException(message);
}
layoutView.PreviousSectionWriters = SectionWriters;
layoutView.BodyContent = bodyContent;
await layoutView.RenderAsync(context);
}
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)
{
WriteTo(Output, value);
@ -242,5 +258,29 @@ namespace Microsoft.AspNet.Mvc.Razor
}
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;
}
}
}
}

View File

@ -135,6 +135,12 @@
<data name="RenderBodyCannotBeCalled" xml:space="preserve">
<value>RenderBody can only be called from a layout page.</value>
</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">
<value>The partial view '{0}' was not found. The following locations were searched:{1}</value>
</data>