Skip to content

Commit 9bd027a

Browse files
authored
Make Partial on PageBase and PageModel work correctly (#13013)
* Make Partial on PageBase and PageModel work correctly Fixes #10438
1 parent c80f7d1 commit 9bd027a

18 files changed

+210
-146
lines changed

src/Mvc/Mvc.RazorPages/ref/Microsoft.AspNetCore.Mvc.RazorPages.netcoreapp3.0.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ public abstract partial class PageBase : Microsoft.AspNetCore.Mvc.Razor.RazorPag
368368
{
369369
protected PageBase() { }
370370
public Microsoft.AspNetCore.Http.HttpContext HttpContext { get { throw null; } }
371+
public Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider MetadataProvider { get { throw null; } set { } }
371372
public Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary ModelState { get { throw null; } }
372373
public Microsoft.AspNetCore.Mvc.RazorPages.PageContext PageContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute]set { } }
373374
public Microsoft.AspNetCore.Http.HttpRequest Request { get { throw null; } }
@@ -500,6 +501,7 @@ public abstract partial class PageModel : Microsoft.AspNetCore.Mvc.Filters.IAsyn
500501
{
501502
protected PageModel() { }
502503
public Microsoft.AspNetCore.Http.HttpContext HttpContext { get { throw null; } }
504+
public Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider MetadataProvider { get { throw null; } set { } }
503505
public Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary ModelState { get { throw null; } }
504506
[Microsoft.AspNetCore.Mvc.RazorPages.PageContextAttribute]
505507
public Microsoft.AspNetCore.Mvc.RazorPages.PageContext PageContext { get { throw null; } set { } }

src/Mvc/Mvc.RazorPages/src/PageBase.cs

Lines changed: 55 additions & 49 deletions
Large diffs are not rendered by default.

src/Mvc/Mvc.RazorPages/src/PageModel.cs

Lines changed: 57 additions & 51 deletions
Large diffs are not rendered by default.

src/Mvc/Mvc.RazorPages/test/PageModelTest.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1898,13 +1898,15 @@ public async Task AsyncPageHandlerSelectingMethod_InvokeSyncMethods()
18981898
public void PartialView_WithName()
18991899
{
19001900
// Arrange
1901-
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary());
1901+
var modelMetadataProvider = new EmptyModelMetadataProvider();
1902+
var viewData = new ViewDataDictionary(modelMetadataProvider, new ModelStateDictionary());
19021903
var pageModel = new TestPageModel
19031904
{
19041905
PageContext = new PageContext
19051906
{
19061907
ViewData = viewData
1907-
}
1908+
},
1909+
MetadataProvider = modelMetadataProvider,
19081910
};
19091911

19101912
// Act
@@ -1913,20 +1915,22 @@ public void PartialView_WithName()
19131915
// Assert
19141916
Assert.NotNull(result);
19151917
Assert.Equal("LoginStatus", result.ViewName);
1916-
Assert.Same(viewData, result.ViewData);
1918+
Assert.Null(result.Model);
19171919
}
19181920

19191921
[Fact]
19201922
public void PartialView_WithNameAndModel()
19211923
{
19221924
// Arrange
1923-
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary());
1925+
var modelMetadataProvider = new EmptyModelMetadataProvider();
1926+
var viewData = new ViewDataDictionary(modelMetadataProvider, new ModelStateDictionary());
19241927
var pageModel = new TestPageModel
19251928
{
19261929
PageContext = new PageContext
19271930
{
19281931
ViewData = viewData
1929-
}
1932+
},
1933+
MetadataProvider = modelMetadataProvider,
19301934
};
19311935
var model = new { Username = "Admin" };
19321936

@@ -1937,7 +1941,6 @@ public void PartialView_WithNameAndModel()
19371941
Assert.NotNull(result);
19381942
Assert.Equal("LoginStatus", result.ViewName);
19391943
Assert.Equal(model, result.Model);
1940-
Assert.Same(viewData, result.ViewData);
19411944
}
19421945

19431946
[Fact]

src/Mvc/Mvc.RazorPages/test/PageTest.cs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1700,36 +1700,42 @@ public void StatusCode_SetsStatusCode()
17001700
public void PartialView_WithName()
17011701
{
17021702
// Arrange
1703-
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary());
1703+
var modelMetadataProvider = new EmptyModelMetadataProvider();
1704+
var viewData = new ViewDataDictionary(modelMetadataProvider, new ModelStateDictionary());
17041705
var pageModel = new TestPage
17051706
{
17061707
ViewContext = new ViewContext
17071708
{
17081709
ViewData = viewData
1709-
}
1710+
},
1711+
MetadataProvider = modelMetadataProvider,
17101712
};
1713+
viewData.Model = pageModel;
17111714

17121715
// Act
17131716
var result = pageModel.Partial("LoginStatus");
17141717

17151718
// Assert
17161719
Assert.NotNull(result);
17171720
Assert.Equal("LoginStatus", result.ViewName);
1718-
Assert.Same(viewData, result.ViewData);
1721+
Assert.Null(result.Model);
17191722
}
17201723

17211724
[Fact]
17221725
public void PartialView_WithNameAndModel()
17231726
{
17241727
// Arrange
1725-
var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary());
1728+
var modelMetadataProvider = new EmptyModelMetadataProvider();
1729+
var viewData = new ViewDataDictionary(modelMetadataProvider, new ModelStateDictionary());
17261730
var pageModel = new TestPage
17271731
{
17281732
ViewContext = new ViewContext
17291733
{
17301734
ViewData = viewData
1731-
}
1735+
},
1736+
MetadataProvider = modelMetadataProvider,
17321737
};
1738+
viewData.Model = pageModel;
17331739
var model = new { Username = "Admin" };
17341740

17351741
// Act
@@ -1739,7 +1745,6 @@ public void PartialView_WithNameAndModel()
17391745
Assert.NotNull(result);
17401746
Assert.Equal("LoginStatus", result.ViewName);
17411747
Assert.Equal(model, result.Model);
1742-
Assert.Same(viewData, result.ViewData);
17431748
}
17441749

17451750
[Fact]

src/Mvc/samples/MvcSandbox/Pages/PagesHome.cshtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
@page
2-
@model TestModel
2+
@model PagesHome
33
@{
44

55
ViewData["Title"] = "Hello from pages";

src/Mvc/samples/MvcSandbox/Models/TestModel.cs renamed to src/Mvc/samples/MvcSandbox/Pages/PagesHome.cshtml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
namespace MvcSandbox
88
{
9-
public class TestModel : PageModel
9+
public class PagesHome : PageModel
1010
{
1111
public string Name { get; private set; } = "World";
1212

src/Mvc/test/Mvc.FunctionalTests/RazorPagesTest.cs

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,23 +144,43 @@ public async Task Page_Handler_ReturnTypeImplementsIActionResult()
144144
}
145145

146146
[Fact]
147-
public async Task Page_Handler_ReturnPartialWithoutModel()
147+
public async Task PageWithoutModel_ReturnPartial()
148148
{
149149
// Act
150-
var document = await Client.GetHtmlDocumentAsync("RenderPartialWithoutModel");
150+
using var document = await Client.GetHtmlDocumentAsync("PageWithoutModelRenderPartial");
151151

152152
var element = document.RequiredQuerySelector("#content");
153-
Assert.Equal("Welcome, Guest", element.TextContent);
153+
Assert.Equal("Hello from Razor Page", element.TextContent);
154154
}
155155

156156
[Fact]
157-
public async Task Page_Handler_ReturnPartialWithModel()
157+
public async Task PageWithModel_Works()
158158
{
159159
// Act
160-
var document = await Client.GetHtmlDocumentAsync("RenderPartialWithModel");
160+
using var document = await Client.GetHtmlDocumentAsync("RenderPartial");
161161

162162
var element = document.RequiredQuerySelector("#content");
163-
Assert.Equal("Welcome, Admin", element.TextContent);
163+
Assert.Equal("Hello from RenderPartialModel", element.TextContent);
164+
}
165+
166+
[Fact]
167+
public async Task PageWithModel_PartialUsingPageModelWorks()
168+
{
169+
// Act
170+
using var document = await Client.GetHtmlDocumentAsync("RenderPartial/UsePageModelAsPartialModel");
171+
172+
var element = document.RequiredQuerySelector("#content");
173+
Assert.Equal("Hello from RenderPartialWithModel", element.TextContent);
174+
}
175+
176+
[Fact]
177+
public async Task PageWithModel_PartialWithNoModel()
178+
{
179+
// Act
180+
using var document = await Client.GetHtmlDocumentAsync("RenderPartial/NoPartialModel");
181+
182+
var element = document.RequiredQuerySelector("#content");
183+
Assert.Equal("Hello default", element.TextContent);
164184
}
165185

166186
[Fact]
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
namespace RazorPagesWebSite.Models
5+
{
6+
public class RenderPartialModel
7+
{
8+
public string Value { get; set; }
9+
}
10+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@page
2+
@using RazorPagesWebSite.Models
3+
4+
@functions {
5+
public IActionResult OnGet() => Partial("_RenderPartial", new RenderPartialModel { Value = "Hello from Razor Page" });
6+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
@page "{handler?}"
2+
@model RazorPagesWebSite.RenderPartialWithModel
3+
4+
@{
5+
throw new Exception("This should not be called");
6+
7+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using Microsoft.AspNetCore.Mvc;
5+
using Microsoft.AspNetCore.Mvc.RazorPages;
6+
using RazorPagesWebSite.Models;
7+
8+
namespace RazorPagesWebSite
9+
{
10+
public class RenderPartialWithModel : PageModel
11+
{
12+
public string Text { get; set; } = $"Hello from {nameof(RenderPartialWithModel)}";
13+
14+
public IActionResult OnGet() => Partial("_RenderPartial", new RenderPartialModel { Value = $"Hello from {nameof(RenderPartialModel)}" });
15+
16+
public IActionResult OnGetUsePageModelAsPartialModel() => Partial("_RenderPartialPageModel", this);
17+
18+
public IActionResult OnGetNoPartialModel() => Partial("_RenderPartial");
19+
}
20+
}

src/Mvc/test/WebSites/RazorPagesWebSite/RenderPartialWithModel.cs

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/Mvc/test/WebSites/RazorPagesWebSite/RenderPartialWithModel.cshtml

Lines changed: 0 additions & 4 deletions
This file was deleted.

src/Mvc/test/WebSites/RazorPagesWebSite/RenderPartialWithoutModel.cshtml

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/Mvc/test/WebSites/RazorPagesWebSite/Views/Shared/_PartialWithoutModel.cshtml

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@using RazorPagesWebSite.Models
2+
@model RenderPartialModel
3+
4+
<span id="content">@(Model?.Value ?? "Hello default")</span>
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
@model RazorPagesWebSite.RenderPartialWithModel
22

3-
<span id="content">Welcome, @Model.Username</span>
3+
<span id="content">@Model.Text</span>

0 commit comments

Comments
 (0)