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

Commit

Permalink
Do not override default Layout value
Browse files Browse the repository at this point in the history
  • Loading branch information
dougbu committed Dec 15, 2015
1 parent 29ea696 commit 1b7e672
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 5 deletions.
15 changes: 11 additions & 4 deletions src/Microsoft.AspNet.Mvc.Razor/RazorView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,12 @@ private async Task RenderViewStartsAsync(ViewContext context)
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)

This comment has been minimized.

Copy link
@pranavkm

pranavkm Dec 15, 2015

Contributor

Should this instead check if viewStart.Layout != null? cc @sebastienros

This comment has been minimized.

Copy link
@dougbu

dougbu Dec 15, 2015

Author Member

Why should a setting done when a page instance is created have priority over a setting the user explicitly put in a _ViewStart.cshtml file?

This comment has been minimized.

Copy link
@pranavkm

pranavkm Dec 15, 2015

Contributor

We disallow resetting it now (since nulls are never transferred). This follows the behavior.

This comment has been minimized.

Copy link
@sebastienros

sebastienros Dec 15, 2015

Member

I think @dougbu is right, I didn't mention this case, but if an intermediate _ViewStart.cshtml doesn't define the layout, it should not override the previous one.

This comment has been minimized.

Copy link
@pranavkm

pranavkm Dec 15, 2015

Contributor

👍

{
viewStart.Layout = layout;
}

await RenderPageCoreAsync(viewStart, context);

Expand All @@ -170,8 +174,11 @@ private async Task RenderViewStartsAsync(ViewContext context)
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(
Expand Down
97 changes: 96 additions & 1 deletion test/Microsoft.AspNet.Mvc.Razor.Test/RazorViewTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
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;
Expand Down Expand Up @@ -359,6 +358,102 @@ public async Task RenderAsync_ExecutesViewStart()
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()
{
Expand Down

0 comments on commit 1b7e672

Please sign in to comment.