Do not override default `Layout` value

- #3745
This commit is contained in:
Doug Bunting 2015-12-14 19:09:57 -08:00
parent 29ea696c5a
commit 1b7e67211f
2 changed files with 107 additions and 5 deletions

View File

@ -155,8 +155,12 @@ namespace Microsoft.AspNet.Mvc.Razor
var viewStart = ViewStartPages[i];
context.ExecutingFilePath = viewStart.Path;
// Copy the layout value from the previous view start (if any) to the current.
viewStart.Layout = layout;
// If non-null, copy the layout value from the previous view start to the current. Otherwise leave
// Layout default alone.
if (layout != null)
{
viewStart.Layout = layout;
}
await RenderPageCoreAsync(viewStart, context);
@ -170,8 +174,11 @@ namespace Microsoft.AspNet.Mvc.Razor
context.ExecutingFilePath = oldFilePath;
}
// Copy the layout value from the view start page(s) (if any) to the entry page.
RazorPage.Layout = layout;
// If non-null, copy the layout value from the view start page(s) to the entry page.
if (layout != null)
{
RazorPage.Layout = layout;
}
}
private async Task RenderLayoutAsync(

View File

@ -6,7 +6,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Http.Features;
using Microsoft.AspNet.Http.Internal;
using Microsoft.AspNet.Mvc.Abstractions;
using Microsoft.AspNet.Mvc.ModelBinding;
@ -359,6 +358,102 @@ namespace Microsoft.AspNet.Mvc.Razor
activator.Verify();
}
[Fact]
public async Task RenderAsync_ExecutesDefaultLayout()
{
// Arrange
var path = "/Views/Home/Index.cshtml";
var layoutPath = "/Views/_Shared/_Layout.cshtml";
var page = new TestableRazorPage(p => { })
{
Path = path,
// Initialize Layout property when instantiated.
Layout = layoutPath,
};
var layoutExecuted = false;
var layout = new TestableRazorPage(
p =>
{
layoutExecuted = true;
p.RenderBodyPublic();
})
{
Path = layoutPath,
};
var viewEngine = new Mock<IRazorViewEngine>(MockBehavior.Strict);
viewEngine
.Setup(engine => engine.GetPage(path, layoutPath))
.Returns(new RazorPageResult(layoutPath, layout));
var view = new RazorView(
viewEngine.Object,
Mock.Of<IRazorPageActivator>(),
new IRazorPage[0],
page,
new HtmlTestEncoder());
var context = CreateViewContext(view);
// Act
await view.RenderAsync(context);
// Assert
Assert.True(layoutExecuted);
}
[Fact]
public async Task RenderAsync_ExecutesDefaultLayout_WithViewStart()
{
// Arrange
var path = "/Views/Home/Index.cshtml";
var layoutPath = "/Views/_Shared/_Layout.cshtml";
var viewStartPath = "/Views/_ViewStart.cshtml";
var viewStart = new TestableRazorPage(p => { })
{
Path = viewStartPath,
};
var page = new TestableRazorPage(p => { })
{
Path = path,
// Initialize Layout property when instantiated.
Layout = layoutPath,
};
var layoutExecuted = false;
var layout = new TestableRazorPage(
p =>
{
layoutExecuted = true;
p.RenderBodyPublic();
})
{
Path = layoutPath,
};
var viewEngine = new Mock<IRazorViewEngine>(MockBehavior.Strict);
viewEngine
.Setup(engine => engine.GetAbsolutePath(viewStartPath, /* pagePath */ null))
.Returns<string>(null);
viewEngine
.Setup(engine => engine.GetPage(path, layoutPath))
.Returns(new RazorPageResult(layoutPath, layout));
var view = new RazorView(
viewEngine.Object,
Mock.Of<IRazorPageActivator>(),
new[] { viewStart },
page,
new HtmlTestEncoder());
var context = CreateViewContext(view);
// Act
await view.RenderAsync(context);
// Assert
Assert.True(layoutExecuted);
}
[Fact]
public async Task RenderAsync_ThrowsIfLayoutPageCannotBeFound_MessageUsesGetPageLocations()
{