From 2aca8810d38272cd8ca34da28365f4c71f75806d Mon Sep 17 00:00:00 2001 From: ryanbrandenburg Date: Mon, 1 Feb 2016 10:57:15 -0800 Subject: [PATCH] * Give message correct path. --- .../Properties/Resources.Designer.cs | 8 +++---- .../RazorPage.cs | 8 +++++-- .../Resources.resx | 2 +- .../RazorViewLocationSpecificationTest.cs | 17 +++++++++++++++ .../RazorPageTest.cs | 18 +++++++++++----- .../PartialViewEngineController.cs | 5 +++++ .../PartialMissingSection.cshtml | 3 +++ .../ViewPartialMissingSection.cshtml | 4 ++++ .../Views/Shared/_PartialLayout.cshtml | 21 +++++++++++++++++++ 9 files changed, 74 insertions(+), 12 deletions(-) create mode 100644 test/WebSites/RazorWebSite/Views/PartialViewEngine/PartialMissingSection.cshtml create mode 100644 test/WebSites/RazorWebSite/Views/PartialViewEngine/ViewPartialMissingSection.cshtml create mode 100644 test/WebSites/RazorWebSite/Views/Shared/_PartialLayout.cshtml diff --git a/src/Microsoft.AspNetCore.Mvc.Razor/Properties/Resources.Designer.cs b/src/Microsoft.AspNetCore.Mvc.Razor/Properties/Resources.Designer.cs index 174f0ecf00..2d17448aec 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor/Properties/Resources.Designer.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor/Properties/Resources.Designer.cs @@ -267,7 +267,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor } /// - /// Section '{0}' is not defined in path '{1}'. + /// The layout page '{0}' cannot find the section '{1}' in the content page '{2}'. /// internal static string SectionNotDefined { @@ -275,11 +275,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor } /// - /// Section '{0}' is not defined in path '{1}'. + /// The layout page '{0}' cannot find the section '{1}' in the content page '{2}'. /// - internal static string FormatSectionNotDefined(object p0, object p1) + internal static string FormatSectionNotDefined(object p0, object p1, object p2) { - return string.Format(CultureInfo.CurrentCulture, GetString("SectionNotDefined"), p0, p1); + return string.Format(CultureInfo.CurrentCulture, GetString("SectionNotDefined"), p0, p1, p2); } /// diff --git a/src/Microsoft.AspNetCore.Mvc.Razor/RazorPage.cs b/src/Microsoft.AspNetCore.Mvc.Razor/RazorPage.cs index 1d6b565403..4def724109 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor/RazorPage.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor/RazorPage.cs @@ -443,7 +443,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor // null or false. Consequently defer the prefix generation until we encounter the attribute value. if (attributeValuesCount != 1) { - WritePositionTaggedLiteral(writer, prefix, prefixOffset); + WritePositionTaggedLiteral(writer, prefix, prefixOffset); } } @@ -800,7 +800,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor else if (required) { // If the section is not found, and it is not optional, throw an error. - throw new InvalidOperationException(Resources.FormatSectionNotDefined(sectionName, Path)); + var message = Resources.FormatSectionNotDefined( + ViewContext.ExecutingFilePath, + sectionName, + ViewContext.View.Path); + throw new InvalidOperationException(message); } else { diff --git a/src/Microsoft.AspNetCore.Mvc.Razor/Resources.resx b/src/Microsoft.AspNetCore.Mvc.Razor/Resources.resx index f227993316..6c36f0d352 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor/Resources.resx +++ b/src/Microsoft.AspNetCore.Mvc.Razor/Resources.resx @@ -166,7 +166,7 @@ {0} invocation in '{1}' is invalid. The section '{2}' has already been rendered. - Section '{0}' is not defined in path '{1}'. + The layout page '{0}' cannot find the section '{1}' in the content page '{2}'. The following sections have been defined but have not been rendered by the page at '{0}': '{1}'. diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/RazorViewLocationSpecificationTest.cs b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/RazorViewLocationSpecificationTest.cs index 450ae78d85..517bf01dd7 100644 --- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/RazorViewLocationSpecificationTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/RazorViewLocationSpecificationTest.cs @@ -4,6 +4,7 @@ using System.Net.Http; using System.Threading.Tasks; using Xunit; +using System.Net; namespace Microsoft.AspNetCore.Mvc.FunctionalTests { @@ -93,5 +94,21 @@ Non Shared Partial // Assert Assert.Equal(expected, body.Trim(), ignoreLineEndingDifferences: true); } + + [Fact] + public async Task PartialLayout_ThrowsIfRequiredSectionMissing() + { + // Arrange + var path = "http://localhost/PartialViewEngine/ViewPartialMissingSection"; + + // Act + var content = await (await Client.GetAsync(path)).Content.ReadAsStringAsync(); + + // Assert + Assert.Contains( + "The layout page '/Views/Shared/_PartialLayout.cshtml' cannot find the section " + + "'section' in the content page '/Views/PartialViewEngine/PartialMissingSection.cshtml'.", + WebUtility.HtmlDecode(content)); + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageTest.cs index 64fe22948a..b9646a956e 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageTest.cs @@ -284,11 +284,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor public async Task RenderSection_ThrowsIfRequiredSectionIsNotFound() { // Arrange + var context = CreateViewContext(viewPath: "/Views/TestPath/Test.cshtml"); + context.ExecutingFilePath = "/Views/Shared/_Layout.cshtml"; var page = CreatePage(v => { - v.Path = "/Views/TestPath/Test.cshtml"; v.RenderSection("bar"); - }); + }, context: context); page.PreviousSectionWriters = new Dictionary { { "baz", _nullRenderAsyncDelegate } @@ -296,7 +297,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor // Act & Assert var ex = await Assert.ThrowsAsync(() => page.ExecuteAsync()); - Assert.Equal("Section 'bar' is not defined in path '/Views/TestPath/Test.cshtml'.", ex.Message); + var message = $"The layout page '/Views/Shared/_Layout.cshtml' cannot find the section 'bar'" + + " in the content page '/Views/TestPath/Test.cshtml'."; + Assert.Equal(message, ex.Message); } [Fact] @@ -1188,7 +1191,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor return view.Object; } - private static ViewContext CreateViewContext(TextWriter writer = null) + private static ViewContext CreateViewContext(TextWriter writer = null, string viewPath = null) { writer = writer ?? new StringWriter(); var httpContext = new DefaultHttpContext(); @@ -1200,9 +1203,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor httpContext, new RouteData(), new ActionDescriptor()); + var viewMock = new Mock(); + if (!string.IsNullOrEmpty(viewPath)) + { + viewMock.Setup(v => v.Path).Returns(viewPath); + } return new ViewContext( actionContext, - Mock.Of(), + viewMock.Object, new ViewDataDictionary(new EmptyModelMetadataProvider()), Mock.Of(), writer, diff --git a/test/WebSites/RazorWebSite/Controllers/PartialViewEngineController.cs b/test/WebSites/RazorWebSite/Controllers/PartialViewEngineController.cs index 484f052997..d7fe08f716 100644 --- a/test/WebSites/RazorWebSite/Controllers/PartialViewEngineController.cs +++ b/test/WebSites/RazorWebSite/Controllers/PartialViewEngineController.cs @@ -42,5 +42,10 @@ namespace RazorWebSite.Controllers }; return PartialView(model); } + + public IActionResult ViewPartialMissingSection() + { + return View(); + } } } \ No newline at end of file diff --git a/test/WebSites/RazorWebSite/Views/PartialViewEngine/PartialMissingSection.cshtml b/test/WebSites/RazorWebSite/Views/PartialViewEngine/PartialMissingSection.cshtml new file mode 100644 index 0000000000..70604444b4 --- /dev/null +++ b/test/WebSites/RazorWebSite/Views/PartialViewEngine/PartialMissingSection.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_PartialLayout"; +} \ No newline at end of file diff --git a/test/WebSites/RazorWebSite/Views/PartialViewEngine/ViewPartialMissingSection.cshtml b/test/WebSites/RazorWebSite/Views/PartialViewEngine/ViewPartialMissingSection.cshtml new file mode 100644 index 0000000000..12619d26bf --- /dev/null +++ b/test/WebSites/RazorWebSite/Views/PartialViewEngine/ViewPartialMissingSection.cshtml @@ -0,0 +1,4 @@ +@{ + Layout = null; +} +@Html.Partial("PartialMissingSection") \ No newline at end of file diff --git a/test/WebSites/RazorWebSite/Views/Shared/_PartialLayout.cshtml b/test/WebSites/RazorWebSite/Views/Shared/_PartialLayout.cshtml new file mode 100644 index 0000000000..89eeeec8cc --- /dev/null +++ b/test/WebSites/RazorWebSite/Views/Shared/_PartialLayout.cshtml @@ -0,0 +1,21 @@ + + + + + + +
+ @RenderBody() +
+ @{ + try + { + RenderSection("section"); + } + catch (InvalidOperationException ex) + { +

@ex.Message

+ } + } + +