* Give message correct path.

This commit is contained in:
ryanbrandenburg 2016-02-01 10:57:15 -08:00
parent d1fdc22b9b
commit 2aca8810d3
9 changed files with 74 additions and 12 deletions

View File

@ -267,7 +267,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
}
/// <summary>
/// Section '{0}' is not defined in path '{1}'.
/// The layout page '{0}' cannot find the section '{1}' in the content page '{2}'.
/// </summary>
internal static string SectionNotDefined
{
@ -275,11 +275,11 @@ namespace Microsoft.AspNetCore.Mvc.Razor
}
/// <summary>
/// Section '{0}' is not defined in path '{1}'.
/// The layout page '{0}' cannot find the section '{1}' in the content page '{2}'.
/// </summary>
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);
}
/// <summary>

View File

@ -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
{

View File

@ -166,7 +166,7 @@
<value>{0} invocation in '{1}' is invalid. The section '{2}' has already been rendered.</value>
</data>
<data name="SectionNotDefined" xml:space="preserve">
<value>Section '{0}' is not defined in path '{1}'.</value>
<value>The layout page '{0}' cannot find the section '{1}' in the content page '{2}'.</value>
</data>
<data name="SectionsNotRendered" xml:space="preserve">
<value>The following sections have been defined but have not been rendered by the page at '{0}': '{1}'.</value>

View File

@ -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));
}
}
}

View File

@ -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<string, RenderAsyncDelegate>
{
{ "baz", _nullRenderAsyncDelegate }
@ -296,7 +297,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor
// Act & Assert
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => 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<IView>();
if (!string.IsNullOrEmpty(viewPath))
{
viewMock.Setup(v => v.Path).Returns(viewPath);
}
return new ViewContext(
actionContext,
Mock.Of<IView>(),
viewMock.Object,
new ViewDataDictionary(new EmptyModelMetadataProvider()),
Mock.Of<ITempDataDictionary>(),
writer,

View File

@ -42,5 +42,10 @@ namespace RazorWebSite.Controllers
};
return PartialView(model);
}
public IActionResult ViewPartialMissingSection()
{
return View();
}
}
}

View File

@ -0,0 +1,3 @@
@{
Layout = "_PartialLayout";
}

View File

@ -0,0 +1,4 @@
@{
Layout = null;
}
<partial>@Html.Partial("PartialMissingSection")</partial>

View File

@ -0,0 +1,21 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div>
@RenderBody()
</div>
@{
try
{
RenderSection("section");
}
catch (InvalidOperationException ex)
{
<p>@ex.Message</p>
}
}
</body>
</html>