parent
094b61dfc6
commit
946b64143e
|
|
@ -60,21 +60,15 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
{
|
||||
model.RouteValues.Add("page", model.ViewEnginePath);
|
||||
|
||||
if (AttributeRouteModel.IsOverridePattern(routeTemplate))
|
||||
{
|
||||
throw new InvalidOperationException(string.Format(
|
||||
Resources.PageActionDescriptorProvider_RouteTemplateCannotBeOverrideable,
|
||||
model.RelativePath));
|
||||
}
|
||||
|
||||
var selectorModel = CreateSelectorModel(pageRoute, routeTemplate);
|
||||
model.Selectors.Add(selectorModel);
|
||||
|
||||
var fileName = Path.GetFileName(model.RelativePath);
|
||||
if (string.Equals(IndexFileName, fileName, StringComparison.OrdinalIgnoreCase))
|
||||
if (!AttributeRouteModel.IsOverridePattern(routeTemplate) &&
|
||||
string.Equals(IndexFileName, fileName, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
// For pages ending in /Index.cshtml, we want to allow incoming routing, but
|
||||
// force outgoing routes to match to the path sans /Index.
|
||||
// For pages without an override route, and ending in /Index.cshtml, we want to allow
|
||||
// incoming routing, but force outgoing routes to match to the path sans /Index.
|
||||
selectorModel.AttributeRouteModel.SuppressLinkGeneration = true;
|
||||
|
||||
var index = pageRoute.LastIndexOf('/');
|
||||
|
|
|
|||
|
|
@ -117,9 +117,6 @@
|
|||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="PageActionDescriptorProvider_RouteTemplateCannotBeOverrideable" xml:space="preserve">
|
||||
<value>The route for the page at '{0}' cannot start with / or ~/. Pages do not support overriding the file path of the page.</value>
|
||||
</data>
|
||||
<data name="PropertyOfTypeCannotBeNull" xml:space="preserve">
|
||||
<value>The '{0}' property of '{1}' must not be null.</value>
|
||||
</data>
|
||||
|
|
|
|||
|
|
@ -1233,6 +1233,16 @@ Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary`1[AspNetCore.InjectedPa
|
|||
Assert.Equal(HttpStatusCode.Redirect, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Page_CanOverrideRouteTemplate()
|
||||
{
|
||||
// Arrange & Act
|
||||
var content = await Client.GetStringAsync("like-totally-custom");
|
||||
|
||||
// Assert
|
||||
Assert.Equal("<p>Hey, it's Mr. totally custom here!</p>", content.Trim());
|
||||
}
|
||||
|
||||
private async Task AddAntiforgeryHeaders(HttpRequestMessage request)
|
||||
{
|
||||
var getResponse = await Client.GetAsync(request.RequestUri);
|
||||
|
|
|
|||
|
|
@ -479,23 +479,40 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void OnProvidersExecuting_ThrowsIfRouteTemplateHasOverridePattern()
|
||||
public void OnProvidersExecuting_AllowsRouteTemplatesWithOverridePattern()
|
||||
{
|
||||
// Arrange
|
||||
var descriptors = new[]
|
||||
{
|
||||
CreateVersion_2_0_Descriptor("/Pages/Index.cshtml"),
|
||||
CreateVersion_2_0_Descriptor("/Pages/Index.cshtml", "~/some-other-prefix"),
|
||||
CreateVersion_2_0_Descriptor("/Pages/Home.cshtml", "/some-prefix"),
|
||||
};
|
||||
|
||||
var provider = CreateProvider(descriptors: descriptors);
|
||||
var context = new PageRouteModelProviderContext();
|
||||
|
||||
// Act & Assert
|
||||
var exception = Assert.Throws<InvalidOperationException>(() => provider.OnProvidersExecuting(context));
|
||||
Assert.Equal(
|
||||
"The route for the page at '/Pages/Home.cshtml' cannot start with / or ~/. Pages do not support overriding the file path of the page.",
|
||||
exception.Message);
|
||||
// Act
|
||||
provider.OnProvidersExecuting(context);
|
||||
|
||||
// Assert
|
||||
Assert.Collection(
|
||||
context.RouteModels,
|
||||
result =>
|
||||
{
|
||||
Assert.Equal("/Pages/Index.cshtml", result.RelativePath);
|
||||
Assert.Equal("/Index", result.ViewEnginePath);
|
||||
Assert.Collection(
|
||||
result.Selectors,
|
||||
selector => Assert.Equal("some-other-prefix", selector.AttributeRouteModel.Template));
|
||||
},
|
||||
result =>
|
||||
{
|
||||
Assert.Equal("/Pages/Home.cshtml", result.RelativePath);
|
||||
Assert.Equal("/Home", result.ViewEnginePath);
|
||||
Assert.Collection(
|
||||
result.Selectors,
|
||||
selector => Assert.Equal("some-prefix", selector.AttributeRouteModel.Template));
|
||||
});
|
||||
}
|
||||
|
||||
private TestCompiledPageRouteModelProvider CreateProvider(
|
||||
|
|
|
|||
|
|
@ -67,6 +67,34 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateRouteModel_DoesNotAddMultipleSelectorsWhenRouteTemplateIsAbsolute()
|
||||
{
|
||||
// Arrange
|
||||
var relativePath = "/Pages/Users/Profile/Index.cshtml";
|
||||
var options = new RazorPagesOptions();
|
||||
var routeModelFactory = new PageRouteModelFactory(options, NullLogger.Instance);
|
||||
|
||||
// Act
|
||||
var routeModel = routeModelFactory.CreateRouteModel(relativePath, "/my-override");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(relativePath, routeModel.RelativePath);
|
||||
Assert.Equal("/Users/Profile/Index", routeModel.ViewEnginePath);
|
||||
|
||||
Assert.Collection(
|
||||
routeModel.Selectors,
|
||||
selector => Assert.Equal("my-override", selector.AttributeRouteModel.Template));
|
||||
|
||||
Assert.Collection(
|
||||
routeModel.RouteValues,
|
||||
kvp =>
|
||||
{
|
||||
Assert.Equal("page", kvp.Key);
|
||||
Assert.Equal("/Users/Profile/Index", kvp.Value);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateAreaRouteModel_AddsSelector()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void OnProvidersExecuting_ThrowsIfRouteTemplateHasOverridePattern()
|
||||
public void OnProvidersExecuting_AllowsRouteTemplateWithOverridePattern()
|
||||
{
|
||||
// Arrange
|
||||
var fileProvider = new TestFileProvider();
|
||||
|
|
@ -296,10 +296,20 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
|||
var provider = new RazorProjectPageRouteModelProvider(project, optionsManager, NullLoggerFactory.Instance);
|
||||
var context = new PageRouteModelProviderContext();
|
||||
|
||||
// Act & Assert
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => provider.OnProvidersExecuting(context));
|
||||
Assert.Equal("The route for the page at '/Index.cshtml' cannot start with / or ~/. Pages do not support overriding the file path of the page.",
|
||||
ex.Message);
|
||||
// Act
|
||||
provider.OnProvidersExecuting(context);
|
||||
|
||||
// Assert
|
||||
Assert.Collection(
|
||||
context.RouteModels,
|
||||
model =>
|
||||
{
|
||||
Assert.Equal("/Index.cshtml", model.RelativePath);
|
||||
Assert.Equal("/Index", model.ViewEnginePath);
|
||||
Assert.Collection(
|
||||
model.Selectors,
|
||||
selector => Assert.Equal("custom-route", selector.AttributeRouteModel.Template));
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
@page "~/like-totally-custom"
|
||||
|
||||
<p>Hey, it's Mr. totally custom here!</p>
|
||||
Loading…
Reference in New Issue