From 94c028a5dfc1cdd2f0495ee9f78315d109753797 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Thu, 3 Apr 2014 15:48:58 -0700 Subject: [PATCH] Adding support for RazorView.IsSectionDefined --- .../Properties/Resources.Designer.cs | 16 ++++ src/Microsoft.AspNet.Mvc.Razor/RazorView.cs | 19 ++++- src/Microsoft.AspNet.Mvc.Razor/Resources.resx | 3 + .../RazorViewTest.cs | 78 ++++++++++++++++++- 4 files changed, 113 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNet.Mvc.Razor/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Mvc.Razor/Properties/Resources.Designer.cs index bab0de1d5a..97c59ef724 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/Properties/Resources.Designer.cs @@ -170,6 +170,22 @@ namespace Microsoft.AspNet.Mvc.Razor return string.Format(CultureInfo.CurrentCulture, GetString("ViewEngine_ViewNotFound"), p0, p1); } + /// + /// The method '{0}' cannot be invoked by this view. + /// + internal static string View_MethodCannotBeCalled + { + get { return GetString("View_MethodCannotBeCalled"); } + } + + /// + /// The method '{0}' cannot be invoked by this view. + /// + internal static string FormatView_MethodCannotBeCalled(object p0) + { + return string.Format(CultureInfo.CurrentCulture, GetString("View_MethodCannotBeCalled"), p0); + } + private static string GetString(string name, params string[] formatterNames) { var value = _resourceManager.GetString(name); diff --git a/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs b/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs index d2a9c692ff..0b4a293e76 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs +++ b/src/Microsoft.AspNet.Mvc.Razor/RazorView.cs @@ -259,6 +259,12 @@ namespace Microsoft.AspNet.Mvc.Razor SectionWriters[name] = action; } + public bool IsSectionDefined([NotNull] string name) + { + EnsureMethodCanBeInvoked("IsSectionDefined"); + return PreviousSectionWriters.ContainsKey(name); + } + public HelperResult RenderSection([NotNull] string name) { return RenderSection(name, required: true); @@ -266,9 +272,10 @@ namespace Microsoft.AspNet.Mvc.Razor public HelperResult RenderSection([NotNull] string name, bool required) { + EnsureMethodCanBeInvoked("RenderSection"); + HelperResult action; - if (PreviousSectionWriters != null && - PreviousSectionWriters.TryGetValue(name, out action)) + if (PreviousSectionWriters.TryGetValue(name, out action)) { return action; } @@ -283,5 +290,13 @@ namespace Microsoft.AspNet.Mvc.Razor return null; } } + + private void EnsureMethodCanBeInvoked(string methodName) + { + if (PreviousSectionWriters == null) + { + throw new InvalidOperationException(Resources.FormatView_MethodCannotBeCalled(methodName)); + } + } } } \ No newline at end of file diff --git a/src/Microsoft.AspNet.Mvc.Razor/Resources.resx b/src/Microsoft.AspNet.Mvc.Razor/Resources.resx index 1d38783d05..995ee0fa76 100644 --- a/src/Microsoft.AspNet.Mvc.Razor/Resources.resx +++ b/src/Microsoft.AspNet.Mvc.Razor/Resources.resx @@ -147,4 +147,7 @@ The view '{0}' was not found. The following locations were searched:{1}. + + The method '{0}' cannot be invoked by this view. + \ No newline at end of file diff --git a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewTest.cs b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewTest.cs index fcc9100950..ad69c60821 100644 --- a/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewTest.cs +++ b/test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewTest.cs @@ -2,6 +2,7 @@ using System.IO; using System.Threading.Tasks; using Microsoft.AspNet.Mvc.Rendering; +using Microsoft.AspNet.Testing; using Moq; using Xunit; @@ -56,6 +57,25 @@ namespace Microsoft.AspNet.Mvc.Razor.Test Assert.Same(actual, expected); } + [Fact] + public async Task RenderSection_ThrowsIfNoPreviousPage() + { + // Arrange + Exception ex = null; + var view = CreateView(v => + { + ex = Assert.Throws(() => v.RenderSection("bar")); + }); + var viewContext = CreateViewContext(layoutView: null); + + // Act + await view.RenderAsync(viewContext); + + // Assert + Assert.Equal("The method 'RenderSection' cannot be invoked by this view.", + ex.Message); + } + [Fact] public async Task RenderSection_ThrowsIfRequiredSectionIsNotFound() { @@ -80,7 +100,63 @@ namespace Microsoft.AspNet.Mvc.Razor.Test // Assert Assert.Equal("Section 'bar' is not defined.", ex.Message); } - + + [Fact] + public void IsSectionDefined_ThrowsIfNoPreviousExecutingPage() + { + // Arrange + var view = CreateView(v => { }); + var viewContext = CreateViewContext(layoutView: null); + + // Act and Assert + ExceptionAssert.Throws(() => view.IsSectionDefined("foo"), + "The method 'IsSectionDefined' cannot be invoked by this view."); + } + + [Fact] + public async Task IsSectionDefined_ReturnsFalseIfSectionNotDefined() + { + // Arrange + bool? actual = null; + var view = CreateView(v => + { + v.DefineSection("baz", new HelperResult(writer => { })); + v.Layout = LayoutPath; + }); + var layoutView = CreateView(v => + { + actual = v.IsSectionDefined("foo"); + }); + + // Act + await view.RenderAsync(CreateViewContext(layoutView)); + + // Assert + Assert.Equal(false, actual); + } + + [Fact] + public async Task IsSectionDefined_ReturnsTrueIfSectionDefined() + { + // Arrange + bool? actual = null; + var view = CreateView(v => + { + v.DefineSection("foo", new HelperResult(writer => { })); + v.Layout = LayoutPath; + }); + var layoutView = CreateView(v => + { + actual = v.IsSectionDefined("foo"); + }); + + // Act + await view.RenderAsync(CreateViewContext(layoutView)); + + // Assert + Assert.Equal(true, actual); + } + public static RazorView CreateView(Action executeAction) { var view = new Mock { CallBase = true };