Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Added path info to RazorPage exceptions #2391

Merged
merged 1 commit into from
Apr 17, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 22 additions & 22 deletions src/Microsoft.AspNet.Mvc.Razor/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 7 additions & 6 deletions src/Microsoft.AspNet.Mvc.Razor/RazorPage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ protected virtual HelperResult RenderBody()
{
if (RenderBodyDelegate == null)
{
var message = Resources.FormatRazorPage_MethodCannotBeCalled(nameof(RenderBody));
var message = Resources.FormatRazorPage_MethodCannotBeCalled(nameof(RenderBody), Path);
throw new InvalidOperationException(message);
}

Expand Down Expand Up @@ -704,7 +704,7 @@ private async Task<HtmlString> RenderSectionAsyncCore(string sectionName, bool r
{
if (_renderedSections.Contains(sectionName))
{
var message = Resources.FormatSectionAlreadyRendered(sectionName);
var message = Resources.FormatSectionAlreadyRendered(nameof(RenderSectionAsync), Path, sectionName);
throw new InvalidOperationException(message);
}

Expand All @@ -721,7 +721,7 @@ private async Task<HtmlString> RenderSectionAsyncCore(string sectionName, bool r
else if (required)
{
// If the section is not found, and it is not optional, throw an error.
throw new InvalidOperationException(Resources.FormatSectionNotDefined(sectionName));
throw new InvalidOperationException(Resources.FormatSectionNotDefined(sectionName, Path));
}
else
{
Expand All @@ -748,14 +748,15 @@ public async Task<HtmlString> FlushAsync()
// change.
if (_writerScopes.Count > 0)
{
throw new InvalidOperationException(Resources.RazorPage_YouCannotFlushWhileInAWritingScope);
throw new InvalidOperationException(
Resources.FormatRazorPage_CannotFlushWhileInAWritingScope(nameof(FlushAsync), Path));
}

// Calls to Flush are allowed if the page does not specify a Layout or if it is executing a section in the
// Layout.
if (!IsLayoutBeingRendered && !string.IsNullOrEmpty(Layout))
{
var message = Resources.FormatLayoutCannotBeRendered(nameof(FlushAsync));
var message = Resources.FormatLayoutCannotBeRendered(Path, nameof(FlushAsync));
throw new InvalidOperationException(message);
}

Expand Down Expand Up @@ -817,7 +818,7 @@ private void EnsureMethodCanBeInvoked(string methodName)
{
if (PreviousSectionWriters == null)
{
throw new InvalidOperationException(Resources.FormatRazorPage_MethodCannotBeCalled(methodName));
throw new InvalidOperationException(Resources.FormatRazorPage_MethodCannotBeCalled(methodName, Path));
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.AspNet.Mvc.Razor/RazorView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ private async Task RenderLayoutAsync(ViewContext context,
// the body content. Throwing this exception wouldn't return a 500 (since content has already been
// written), but a diagnostic component should be able to capture it.

var message = Resources.FormatLayoutCannotBeRendered("FlushAsync");
var message = Resources.FormatLayoutCannotBeRendered(Path, nameof(Razor.RazorPage.FlushAsync));
throw new InvalidOperationException(message);
}

Expand Down
12 changes: 6 additions & 6 deletions src/Microsoft.AspNet.Mvc.Razor/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
<value>The layout view '{0}' could not be located. The following locations were searched:{1}</value>
</data>
<data name="LayoutCannotBeRendered" xml:space="preserve">
<value>A layout page cannot be rendered after '{0}' has been invoked.</value>
<value>Layout page '{0}' cannot be rendered after '{1}' has been invoked.</value>
</data>
<data name="MvcRazorCodeParser_CannotHaveModelAndInheritsKeyword" xml:space="preserve">
<value>The 'inherits' keyword is not allowed when a '{0}' keyword is used.</value>
Expand All @@ -147,14 +147,14 @@
<data name="RazorPage_ThereIsNoActiveWritingScopeToEnd" xml:space="preserve">
<value>There is no active writing scope to end.</value>
</data>
<data name="RazorPage_YouCannotFlushWhileInAWritingScope" xml:space="preserve">
<value>You cannot flush while inside a writing scope.</value>
<data name="RazorPage_CannotFlushWhileInAWritingScope" xml:space="preserve">
<value>The {0} operation cannot be performed while inside a writing scope in '{1}'.</value>
</data>
<data name="RazorPage_NullModelMetadata" xml:space="preserve">
<value>The {0} was unable to provide metadata for expression '{1}'.</value>
</data>
<data name="RazorPage_MethodCannotBeCalled" xml:space="preserve">
<value>{0} can only be called from a layout page.</value>
<value>{0} invocation in '{1}' is invalid. {0} can only be called from a layout page.</value>
</data>
<data name="RenderBodyNotCalled" xml:space="preserve">
<value>{0} has not been called for the page at '{1}'.</value>
Expand All @@ -163,10 +163,10 @@
<value>Section '{0}' is already defined.</value>
</data>
<data name="SectionAlreadyRendered" xml:space="preserve">
<value>The section named '{0}' has already been rendered.</value>
<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.</value>
<value>Section '{0}' is not defined in path '{1}'.</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>
Expand Down
3 changes: 2 additions & 1 deletion test/Microsoft.AspNet.Mvc.FunctionalTests/FlushPointTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ public async Task FlushBeforeCallingLayout()
});
var client = server.CreateClient();

var expectedMessage = "A layout page cannot be rendered after 'FlushAsync' has been invoked.";
var expectedMessage = "Layout page '/Views/FlushPoint/PageWithFlushBeforeLayout.cshtml'" +
" cannot be rendered after 'FlushAsync' has been invoked.";

// Act
var stream = await client.GetStreamAsync("http://localhost/FlushPoint/PageWithFlushBeforeLayout");
Expand Down
42 changes: 31 additions & 11 deletions test/Microsoft.AspNet.Mvc.Razor.Test/RazorPageTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ public async Task StartNewWritingScope_CannotFlushInWritingScope()
var viewContext = CreateViewContext();
var page = CreatePage(async v =>
{
v.Path = "/Views/TestPath/Test.cshtml";
v.StartTagHelperWritingScope();
await v.FlushAsync();
});
Expand All @@ -116,7 +117,8 @@ public async Task StartNewWritingScope_CannotFlushInWritingScope()
() => page.ExecuteAsync());

// Assert
Assert.Equal("You cannot flush while inside a writing scope.", ex.Message);
Assert.Equal("The FlushAsync operation cannot be performed while " +
"inside a writing scope in '/Views/TestPath/Test.cshtml'.", ex.Message);
}

[Fact]
Expand Down Expand Up @@ -229,15 +231,17 @@ public async Task RenderSection_ThrowsIfPreviousSectionWritersIsNotSet()
Exception ex = null;
var page = CreatePage(v =>
{
v.Path = "/Views/TestPath/Test.cshtml";
ex = Assert.Throws<InvalidOperationException>(() => v.RenderSection("bar"));
});

// Act
await page.ExecuteAsync();

// Assert
Assert.Equal("RenderSection can only be called from a layout page.",
ex.Message);
Assert.Equal("RenderSection invocation in '/Views/TestPath/Test.cshtml' is invalid. " +
"RenderSection can only be called from a layout page.",
ex.Message);
}

[Fact]
Expand All @@ -246,6 +250,7 @@ public async Task RenderSection_ThrowsIfRequiredSectionIsNotFound()
// Arrange
var page = CreatePage(v =>
{
v.Path = "/Views/TestPath/Test.cshtml";
v.RenderSection("bar");
});
page.PreviousSectionWriters = new Dictionary<string, RenderAsyncDelegate>
Expand All @@ -257,18 +262,23 @@ public async Task RenderSection_ThrowsIfRequiredSectionIsNotFound()
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => page.ExecuteAsync());

// Assert
Assert.Equal("Section 'bar' is not defined.", ex.Message);
Assert.Equal("Section 'bar' is not defined in path '/Views/TestPath/Test.cshtml'.", ex.Message);
}

[Fact]
public void IsSectionDefined_ThrowsIfPreviousSectionWritersIsNotRegistered()
{
// Arrange
var page = CreatePage(v => { });
var page = CreatePage(v =>
{
v.Path = "/Views/TestPath/Test.cshtml";
});

// Act and Assert
page.ExecuteAsync();
ExceptionAssert.Throws<InvalidOperationException>(() => page.IsSectionDefined("foo"),
"IsSectionDefined can only be called from a layout page.");
"IsSectionDefined invocation in '/Views/TestPath/Test.cshtml' is invalid." +
" IsSectionDefined can only be called from a layout page.");
}

[Fact]
Expand Down Expand Up @@ -326,6 +336,7 @@ public async Task RenderSection_ThrowsIfSectionIsRenderedMoreThanOnce()
var expected = new HelperResult(action: null);
var page = CreatePage(v =>
{
v.Path = "/Views/TestPath/Test.cshtml";
v.RenderSection("header");
v.RenderSection("header");
});
Expand All @@ -338,7 +349,8 @@ public async Task RenderSection_ThrowsIfSectionIsRenderedMoreThanOnce()
var ex = await Assert.ThrowsAsync<InvalidOperationException>(page.ExecuteAsync);

// Assert
Assert.Equal("The section named 'header' has already been rendered.", ex.Message);
Assert.Equal("RenderSectionAsync invocation in '/Views/TestPath/Test.cshtml' is invalid." +
" The section 'header' has already been rendered.", ex.Message);
}

[Fact]
Expand All @@ -348,6 +360,7 @@ public async Task RenderSectionAsync_ThrowsIfSectionIsRenderedMoreThanOnce()
var expected = new HelperResult(action: null);
var page = CreatePage(async v =>
{
v.Path = "/Views/TestPath/Test.cshtml";
await v.RenderSectionAsync("header");
await v.RenderSectionAsync("header");
});
Expand All @@ -360,7 +373,8 @@ public async Task RenderSectionAsync_ThrowsIfSectionIsRenderedMoreThanOnce()
var ex = await Assert.ThrowsAsync<InvalidOperationException>(page.ExecuteAsync);

// Assert
Assert.Equal("The section named 'header' has already been rendered.", ex.Message);
Assert.Equal("RenderSectionAsync invocation in '/Views/TestPath/Test.cshtml' is invalid." +
" The section 'header' has already been rendered.", ex.Message);
}

[Fact]
Expand All @@ -370,6 +384,7 @@ public async Task RenderSectionAsync_ThrowsIfSectionIsRenderedMoreThanOnce_WithS
var expected = new HelperResult(action: null);
var page = CreatePage(async v =>
{
v.Path = "/Views/TestPath/Test.cshtml";
v.RenderSection("header");
await v.RenderSectionAsync("header");
});
Expand All @@ -382,7 +397,8 @@ public async Task RenderSectionAsync_ThrowsIfSectionIsRenderedMoreThanOnce_WithS
var ex = await Assert.ThrowsAsync<InvalidOperationException>(page.ExecuteAsync);

// Assert
Assert.Equal("The section named 'header' has already been rendered.", ex.Message);
Assert.Equal("RenderSectionAsync invocation in '/Views/TestPath/Test.cshtml' is invalid." +
" The section 'header' has already been rendered.", ex.Message);
}

[Fact]
Expand All @@ -392,14 +408,16 @@ public async Task RenderSectionAsync_ThrowsIfNotInvokedFromLayoutPage()
var expected = new HelperResult(action: null);
var page = CreatePage(async v =>
{
v.Path = "/Views/TestPath/Test.cshtml";
await v.RenderSectionAsync("header");
});

// Act
var ex = await Assert.ThrowsAsync<InvalidOperationException>(page.ExecuteAsync);

// Assert
Assert.Equal("RenderSectionAsync can only be called from a layout page.", ex.Message);
Assert.Equal("RenderSectionAsync invocation in '/Views/TestPath/Test.cshtml' is invalid. " +
"RenderSectionAsync can only be called from a layout page.", ex.Message);
}

[Fact]
Expand Down Expand Up @@ -566,11 +584,13 @@ public async Task FlushAsync_InvokesFlushOnWriter()
public async Task FlushAsync_ThrowsIfTheLayoutHasBeenSet()
{
// Arrange
var expected = @"A layout page cannot be rendered after 'FlushAsync' has been invoked.";
var expected = "Layout page '/Views/TestPath/Test.cshtml' cannot be rendered" +
" after 'FlushAsync' has been invoked.";
var writer = new Mock<TextWriter>();
var context = CreateViewContext(writer.Object);
var page = CreatePage(async p =>
{
p.Path = "/Views/TestPath/Test.cshtml";
p.Layout = "foo";
await p.FlushAsync();
}, context);
Expand Down
Loading