parent
bc87c3e9cb
commit
7b2a4ff465
|
|
@ -240,7 +240,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor
|
|||
{
|
||||
var controllerName = GetNormalizedRouteValue(actionContext, ControllerKey);
|
||||
var areaName = GetNormalizedRouteValue(actionContext, AreaKey);
|
||||
var razorPageName = GetNormalizedRouteValue(actionContext, PageKey);
|
||||
string razorPageName = null;
|
||||
if (actionContext.ActionDescriptor.RouteValues.ContainsKey(PageKey))
|
||||
{
|
||||
// Only calculate the Razor Page name if "page" is registered in RouteValues.
|
||||
razorPageName = GetNormalizedRouteValue(actionContext, PageKey);
|
||||
}
|
||||
|
||||
var expanderContext = new ViewLocationExpanderContext(
|
||||
actionContext,
|
||||
pageName,
|
||||
|
|
@ -270,8 +276,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
|
|||
expanderContext.IsMainPage,
|
||||
expanderValues);
|
||||
|
||||
ViewLocationCacheResult cacheResult;
|
||||
if (!ViewLookupCache.TryGetValue(cacheKey, out cacheResult))
|
||||
if (!ViewLookupCache.TryGetValue(cacheKey, out ViewLocationCacheResult cacheResult))
|
||||
{
|
||||
_logger.ViewLookupCacheMiss(cacheKey.ViewName, cacheKey.ControllerName);
|
||||
cacheResult = OnCacheMiss(expanderContext, cacheKey);
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
{
|
||||
public IEnumerable<string> ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable<string> viewLocations)
|
||||
{
|
||||
if (string.IsNullOrEmpty(context.PageName))
|
||||
if ((context.ActionContext.ActionDescriptor is PageActionDescriptor) && !string.IsNullOrEmpty(context.PageName))
|
||||
{
|
||||
// Not a page - just act natural.
|
||||
return viewLocations;
|
||||
return ExpandPageHierarchy();
|
||||
}
|
||||
|
||||
return ExpandPageHierarchy();
|
||||
// Not a page - just act natural.
|
||||
return viewLocations;
|
||||
|
||||
IEnumerable<string> ExpandPageHierarchy()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -376,5 +376,31 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
// Assert
|
||||
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UsingPageRouteParameterInConventionalRouteWorks()
|
||||
{
|
||||
// Arrange
|
||||
var expected = "ConventionalRoute - Hello from mypage";
|
||||
|
||||
// Act
|
||||
var response = await Client.GetStringAsync("/PageRoute/ConventionalRoute/mypage");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, response.Trim());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UsingPageRouteParameterInAttributeRouteWorks()
|
||||
{
|
||||
// Arrange
|
||||
var expected = "AttributeRoute - Hello from test-page";
|
||||
|
||||
// Act
|
||||
var response = await Client.GetStringAsync("/PageRoute/Attribute/test-page");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expected, response.Trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1791,6 +1791,79 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Test
|
|||
Assert.Equal(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ViewEngine_DoesNotSetPageValue_IfItIsNotSpecifiedInRouteValues()
|
||||
{
|
||||
// Arrange
|
||||
var routeValues = new Dictionary<string, object>
|
||||
{
|
||||
{ "controller", "MyController" },
|
||||
{ "action", "MyAction" }
|
||||
};
|
||||
|
||||
var expected = new[] { "some-seed" };
|
||||
var expander = new Mock<IViewLocationExpander>();
|
||||
expander
|
||||
.Setup(e => e.PopulateValues(It.IsAny<ViewLocationExpanderContext>()))
|
||||
.Callback((ViewLocationExpanderContext c) =>
|
||||
{
|
||||
Assert.Equal("MyController", c.ControllerName);
|
||||
Assert.Null(c.PageName);
|
||||
})
|
||||
.Verifiable();
|
||||
|
||||
expander
|
||||
.Setup(e => e.ExpandViewLocations(
|
||||
It.IsAny<ViewLocationExpanderContext>(),
|
||||
It.IsAny<IEnumerable<string>>()))
|
||||
.Returns(expected);
|
||||
|
||||
var viewEngine = CreateViewEngine(expanders: new[] { expander.Object });
|
||||
var context = GetActionContext(routeValues);
|
||||
|
||||
// Act
|
||||
viewEngine.FindView(context, viewName: "Test-view", isMainPage: true);
|
||||
|
||||
// Assert
|
||||
expander.Verify();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ViewEngine_SetsPageValue_IfItIsSpecifiedInRouteValues()
|
||||
{
|
||||
// Arrange
|
||||
var routeValues = new Dictionary<string, object>
|
||||
{
|
||||
{ "page", "MyPage" },
|
||||
};
|
||||
|
||||
var expected = new[] { "some-seed" };
|
||||
var expander = new Mock<IViewLocationExpander>();
|
||||
expander
|
||||
.Setup(e => e.PopulateValues(It.IsAny<ViewLocationExpanderContext>()))
|
||||
.Callback((ViewLocationExpanderContext c) =>
|
||||
{
|
||||
Assert.Equal("MyPage", c.PageName);
|
||||
})
|
||||
.Verifiable();
|
||||
|
||||
expander
|
||||
.Setup(e => e.ExpandViewLocations(
|
||||
It.IsAny<ViewLocationExpanderContext>(),
|
||||
It.IsAny<IEnumerable<string>>()))
|
||||
.Returns(expected);
|
||||
|
||||
var viewEngine = CreateViewEngine(expanders: new[] { expander.Object });
|
||||
var context = GetActionContext(routeValues);
|
||||
context.ActionDescriptor.RouteValues["page"] = "MyPage";
|
||||
|
||||
// Act
|
||||
viewEngine.FindView(context, viewName: "MyView", isMainPage: true);
|
||||
|
||||
// Assert
|
||||
expander.Verify();
|
||||
}
|
||||
|
||||
// Return RazorViewEngine with a page factory provider that is always successful.
|
||||
private RazorViewEngine CreateSuccessfulViewEngine()
|
||||
{
|
||||
|
|
@ -1931,8 +2004,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Test
|
|||
optionsAccessor,
|
||||
new FileProviderRazorProject(
|
||||
Mock.Of<IRazorViewEngineFileProviderAccessor>(a => a.FileProvider == new TestFileProvider())))
|
||||
{
|
||||
}
|
||||
{
|
||||
}
|
||||
|
||||
public TestableRazorViewEngine(
|
||||
IRazorPageFactoryProvider pageFactory,
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||
using Microsoft.AspNetCore.Mvc.Razor;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||
|
|
@ -48,6 +45,28 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
Assert.Equal(locations, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExpandLocations_NoOp_ForNonPageWithPageName()
|
||||
{
|
||||
// Verifies the fix for https://github.com/aspnet/Mvc/issues/6660. This ensures that when PageViewLocationExpander is called
|
||||
// from a non-Razor Page with a route value for "
|
||||
// Arrange
|
||||
var context = CreateContext(pageName: "test");
|
||||
context.ActionContext.ActionDescriptor = new ControllerActionDescriptor();
|
||||
var locations = new string[]
|
||||
{
|
||||
"/ignore-me",
|
||||
};
|
||||
|
||||
var expander = new PageViewLocationExpander();
|
||||
|
||||
// Act
|
||||
var actual = expander.ExpandViewLocations(context, locations);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(locations, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ExpandLocations_NoOp_WhenLocationDoesNotContainPageToken()
|
||||
{
|
||||
|
|
@ -125,8 +144,13 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
|
||||
private ViewLocationExpanderContext CreateContext(string viewName = "_LoginPartial.cshtml", string pageName = null)
|
||||
{
|
||||
var actionContext = new ActionContext
|
||||
{
|
||||
ActionDescriptor = new PageActionDescriptor(),
|
||||
};
|
||||
|
||||
return new ViewLocationExpanderContext(
|
||||
new ActionContext(),
|
||||
actionContext,
|
||||
viewName,
|
||||
controllerName: null,
|
||||
areaName: null,
|
||||
|
|
@ -134,6 +158,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
|||
isMainPage: true)
|
||||
{
|
||||
Values = new Dictionary<string, string>(),
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace BasicWebSite.Controllers
|
||||
{
|
||||
// Verifies that we can use the "page" token in routing in a controller only (no Razor Pages) application
|
||||
// without affecting view lookups.
|
||||
public class PageRouteController : Controller
|
||||
{
|
||||
public IActionResult ConventionalRoute(string page)
|
||||
{
|
||||
ViewData["page"] = page;
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpGet("/PageRoute/Attribute/{page}")]
|
||||
public IActionResult AttributeRoute(string page)
|
||||
{
|
||||
ViewData["page"] = page;
|
||||
return View();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -44,6 +44,7 @@ namespace BasicWebSite
|
|||
routes.MapRoute("ActionAsMethod", "{controller}/{action}",
|
||||
defaults: new { controller = "Home", action = "Index" });
|
||||
|
||||
routes.MapRoute("PageRoute", "{controller}/{action}/{page}");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
AttributeRoute - Hello from @ViewBag.Page
|
||||
|
|
@ -0,0 +1 @@
|
|||
ConventionalRoute - Hello from @ViewBag.Page
|
||||
Loading…
Reference in New Issue