Merge pull request #8551 from dotnet-maestro-bot/merge/release/2.2-to-master
[automated] Merge branch 'release/2.2' => 'master'
This commit is contained in:
commit
523b2223ad
|
|
@ -3,7 +3,7 @@ ASP.NET Core MVC
|
||||||
|
|
||||||
**Note: For ASP.NET MVC 5.x, Web API 2.x, and Web Pages 3.x (not ASP.NET Core), see https://github.com/aspnet/AspNetWebStack**
|
**Note: For ASP.NET MVC 5.x, Web API 2.x, and Web Pages 3.x (not ASP.NET Core), see https://github.com/aspnet/AspNetWebStack**
|
||||||
|
|
||||||
Travis: [](https://travis-ci.org/aspnet/Mvc)
|
Travis: [](https://travis-ci.org/aspnet/Mvc)
|
||||||
|
|
||||||
ASP.NET Core MVC gives you a powerful, patterns-based way to build dynamic websites that enables a clean separation of concerns and gives you full control over markup for enjoyable, agile development. ASP.NET Core MVC includes many features that enable fast, TDD-friendly development for creating sophisticated applications that use the latest web standards.
|
ASP.NET Core MVC gives you a powerful, patterns-based way to build dynamic websites that enables a clean separation of concerns and gives you full control over markup for enjoyable, agile development. ASP.NET Core MVC includes many features that enable fast, TDD-friendly development for creating sophisticated applications that use the latest web standards.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,6 @@ They makes it easier to test local changes than having the App in the Benchmarks
|
||||||
3. If cloned go to the BenchmarksDriver project
|
3. If cloned go to the BenchmarksDriver project
|
||||||
4. Use the following command as a guideline for running a test using your changes
|
4. Use the following command as a guideline for running a test using your changes
|
||||||
|
|
||||||
`benchmarks --server <server-endpoint> --client <client-endpoint> -j https://raw.githubusercontent.com/aspnet/MVC/dev/benchmarkaps/BasicApi/BasicApi.json`
|
`benchmarks --server <server-endpoint> --client <client-endpoint> -j https://raw.githubusercontent.com/aspnet/MVC/{your branch}/benchmarkaps/BasicApi/BasicApi.json`
|
||||||
|
|
||||||
5. For more info/commands see https://github.com/aspnet/benchmarks/blob/dev/src/BenchmarksDriver/README.md
|
5. For more info/commands see https://github.com/aspnet/benchmarks/blob/master/src/BenchmarksDriver/README.md
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,8 @@ namespace Microsoft.AspNetCore.Mvc.ApplicationModels
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// An <see cref="IActionModelConvention"/> that sets attribute routing token replacement
|
/// An <see cref="IActionModelConvention"/> that sets attribute routing token replacement
|
||||||
/// to use the specified <see cref="IOutboundParameterTransformer"/> on <see cref="ActionModel"/> selectors.
|
/// to use the specified <see cref="IOutboundParameterTransformer"/> on <see cref="ActionModel"/>.
|
||||||
|
/// This convention does not effect Razor page routes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class RouteTokenTransformerConvention : IActionModelConvention
|
public class RouteTokenTransformerConvention : IActionModelConvention
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
// 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 Microsoft.AspNetCore.Routing;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Mvc.ApplicationModels
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An <see cref="IPageRouteModelConvention"/> that sets page route resolution
|
||||||
|
/// to use the specified <see cref="IOutboundParameterTransformer"/> on <see cref="PageRouteModel"/>.
|
||||||
|
/// This convention does not effect controller action routes.
|
||||||
|
/// </summary>
|
||||||
|
public class PageRouteTransformerConvention : IPageRouteModelConvention
|
||||||
|
{
|
||||||
|
private IOutboundParameterTransformer _parameterTransformer;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of <see cref="PageRouteTransformerConvention"/> with the specified <see cref="IOutboundParameterTransformer"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parameterTransformer">The <see cref="IOutboundParameterTransformer"/> to use resolve page routes.</param>
|
||||||
|
public PageRouteTransformerConvention(IOutboundParameterTransformer parameterTransformer)
|
||||||
|
{
|
||||||
|
if (parameterTransformer == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(parameterTransformer));
|
||||||
|
}
|
||||||
|
|
||||||
|
_parameterTransformer = parameterTransformer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Apply(PageRouteModel model)
|
||||||
|
{
|
||||||
|
if (ShouldApply(model))
|
||||||
|
{
|
||||||
|
model.Properties[typeof(IOutboundParameterTransformer)] = _parameterTransformer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual bool ShouldApply(PageRouteModel action) => true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,10 +4,15 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||||
using Microsoft.AspNetCore.Mvc.Filters;
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Internal;
|
||||||
|
using Microsoft.AspNetCore.Mvc.RazorPages.Internal;
|
||||||
using Microsoft.AspNetCore.Mvc.Routing;
|
using Microsoft.AspNetCore.Mvc.Routing;
|
||||||
|
using Microsoft.AspNetCore.Routing;
|
||||||
|
using Microsoft.AspNetCore.Routing.Patterns;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
|
|
@ -81,7 +86,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
{
|
{
|
||||||
Name = selector.AttributeRouteModel.Name,
|
Name = selector.AttributeRouteModel.Name,
|
||||||
Order = selector.AttributeRouteModel.Order ?? 0,
|
Order = selector.AttributeRouteModel.Order ?? 0,
|
||||||
Template = selector.AttributeRouteModel.Template,
|
Template = TransformPageRoute(model, selector),
|
||||||
SuppressLinkGeneration = selector.AttributeRouteModel.SuppressLinkGeneration,
|
SuppressLinkGeneration = selector.AttributeRouteModel.SuppressLinkGeneration,
|
||||||
SuppressPathMatching = selector.AttributeRouteModel.SuppressPathMatching,
|
SuppressPathMatching = selector.AttributeRouteModel.SuppressPathMatching,
|
||||||
},
|
},
|
||||||
|
|
@ -109,5 +114,35 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure
|
||||||
actions.Add(descriptor);
|
actions.Add(descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string TransformPageRoute(PageRouteModel model, SelectorModel selectorModel)
|
||||||
|
{
|
||||||
|
model.Properties.TryGetValue(typeof(IOutboundParameterTransformer), out var transformer);
|
||||||
|
var pageRouteTransformer = transformer as IOutboundParameterTransformer;
|
||||||
|
|
||||||
|
// Transformer not set on page route
|
||||||
|
if (pageRouteTransformer == null)
|
||||||
|
{
|
||||||
|
return selectorModel.AttributeRouteModel.Template;
|
||||||
|
}
|
||||||
|
|
||||||
|
var pageRouteMetadata = selectorModel.EndpointMetadata.OfType<PageRouteMetadata>().SingleOrDefault();
|
||||||
|
if (pageRouteMetadata == null)
|
||||||
|
{
|
||||||
|
// Selector does not have expected metadata. Should never reach here
|
||||||
|
throw new InvalidOperationException("Page selector did not have page route metadata.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var segments = pageRouteMetadata.PageRoute.Split('/');
|
||||||
|
for (var i = 0; i < segments.Length; i++)
|
||||||
|
{
|
||||||
|
segments[i] = pageRouteTransformer.TransformOutbound(segments[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var transformedPageRoute = string.Join("/", segments);
|
||||||
|
|
||||||
|
// Combine transformed page route with template
|
||||||
|
return AttributeRouteModel.CombineTemplates(transformedPageRoute, pageRouteMetadata.RouteTemplate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
|
{
|
||||||
|
// This is used to store the uncombined parts of the final page route
|
||||||
|
internal class PageRouteMetadata
|
||||||
|
{
|
||||||
|
public PageRouteMetadata(string pageRoute, string routeTemplate)
|
||||||
|
{
|
||||||
|
PageRoute = pageRoute;
|
||||||
|
RouteTemplate = routeTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string PageRoute { get; }
|
||||||
|
public string RouteTemplate { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -159,6 +159,10 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal
|
||||||
AttributeRouteModel = new AttributeRouteModel
|
AttributeRouteModel = new AttributeRouteModel
|
||||||
{
|
{
|
||||||
Template = AttributeRouteModel.CombineTemplates(prefix, routeTemplate),
|
Template = AttributeRouteModel.CombineTemplates(prefix, routeTemplate),
|
||||||
|
},
|
||||||
|
EndpointMetadata =
|
||||||
|
{
|
||||||
|
new PageRouteMetadata(prefix, routeTemplate)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,25 +11,6 @@ namespace Microsoft.AspNetCore.Mvc.Test.ApplicationModels
|
||||||
{
|
{
|
||||||
public class RouteTokenTransformerConventionTest
|
public class RouteTokenTransformerConventionTest
|
||||||
{
|
{
|
||||||
[Fact]
|
|
||||||
public void Apply_NullAttributeRouteModel_NoOp()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var convention = new RouteTokenTransformerConvention(new TestParameterTransformer());
|
|
||||||
|
|
||||||
var model = new ActionModel(GetMethodInfo(), Array.Empty<object>());
|
|
||||||
model.Selectors.Add(new SelectorModel()
|
|
||||||
{
|
|
||||||
AttributeRouteModel = null
|
|
||||||
});
|
|
||||||
|
|
||||||
// Act
|
|
||||||
convention.Apply(model);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Null(model.Selectors[0].AttributeRouteModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public void Apply_HasAttributeRouteModel_SetRouteTokenTransformer()
|
public void Apply_HasAttributeRouteModel_SetRouteTokenTransformer()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,18 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
Assert.Equal("/LGPage?another-value=4", responseContent);
|
Assert.Equal("/LGPage?another-value=4", responseContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task GetPathByPage_CanGeneratePathToPage_PathTransformed()
|
||||||
|
{
|
||||||
|
// Act
|
||||||
|
var response = await Client.GetAsync("LG1/LinkToPageWithTransformedPath?id=HelloWorld");
|
||||||
|
var responseContent = await response.Content.ReadAsStringAsync();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
Assert.Equal("/page-route-transformer/test-page/ExtraPath/HelloWorld", responseContent);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task GetPathByPage_CanGeneratePathToPageInArea()
|
public async Task GetPathByPage_CanGeneratePathToPageInArea()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,38 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||||
Assert.Empty(result);
|
Assert.Empty(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Page_PageRouteTransformer()
|
||||||
|
{
|
||||||
|
// Arrange & Act
|
||||||
|
var response = await Client.GetAsync("http://localhost/page-route-transformer/index");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Page_PageRouteTransformer_WithoutIndex()
|
||||||
|
{
|
||||||
|
// Arrange & Act
|
||||||
|
var response = await Client.GetAsync("http://localhost/page-route-transformer");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Page_PageRouteTransformer_RouteParameter()
|
||||||
|
{
|
||||||
|
// Arrange & Act
|
||||||
|
var response = await Client.GetAsync("http://localhost/page-route-transformer/test-page/ExtraPath/World");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||||
|
var body = await response.Content.ReadAsStringAsync();
|
||||||
|
Assert.Equal("Hello from World", body);
|
||||||
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public virtual async Task ConventionalRoutedController_ActionIsReachable()
|
public virtual async Task ConventionalRoutedController_ActionIsReachable()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
// 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.Reflection;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||||
|
using Microsoft.AspNetCore.Routing;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNetCore.Mvc.Test.ApplicationModels
|
||||||
|
{
|
||||||
|
public class PageRouteTransformerConventionTest
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void Apply_SetTransformer()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var transformer = new TestParameterTransformer();
|
||||||
|
var convention = new PageRouteTransformerConvention(transformer);
|
||||||
|
|
||||||
|
var model = new PageRouteModel(string.Empty, string.Empty);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
convention.Apply(model);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.True(model.Properties.TryGetValue(typeof(IOutboundParameterTransformer), out var routeTokenTransformer));
|
||||||
|
Assert.Equal(transformer, routeTokenTransformer);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Apply_ShouldApplyFalse_NoOp()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var transformer = new TestParameterTransformer();
|
||||||
|
var convention = new CustomPageRouteTransformerConvention(transformer);
|
||||||
|
|
||||||
|
var model = new PageRouteModel(string.Empty, string.Empty);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
convention.Apply(model);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.False(model.Properties.TryGetValue(typeof(IOutboundParameterTransformer), out _));
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestParameterTransformer : IOutboundParameterTransformer
|
||||||
|
{
|
||||||
|
public string TransformOutbound(object value)
|
||||||
|
{
|
||||||
|
return value?.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CustomPageRouteTransformerConvention : PageRouteTransformerConvention
|
||||||
|
{
|
||||||
|
public CustomPageRouteTransformerConvention(IOutboundParameterTransformer parameterTransformer) : base(parameterTransformer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool ShouldApply(PageRouteModel action)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -59,6 +59,14 @@ namespace RoutingWebSite
|
||||||
values: QueryToRouteValues(HttpContext.Request.Query));
|
values: QueryToRouteValues(HttpContext.Request.Query));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string LinkToPageWithTransformedPath()
|
||||||
|
{
|
||||||
|
return _linkGenerator.GetPathByPage(
|
||||||
|
HttpContext,
|
||||||
|
page: "/PageRouteTransformer/TestPage",
|
||||||
|
values: QueryToRouteValues(HttpContext.Request.Query));
|
||||||
|
}
|
||||||
|
|
||||||
public string LinkToPageInArea()
|
public string LinkToPageInArea()
|
||||||
{
|
{
|
||||||
var values = QueryToRouteValues(HttpContext.Request.Query);
|
var values = QueryToRouteValues(HttpContext.Request.Query);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
@page
|
||||||
|
@{
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
@page "ExtraPath/{id?}"
|
||||||
|
@{
|
||||||
|
}
|
||||||
|
Hello from @ViewContext.RouteData.Values["id"]
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
@ -15,6 +16,8 @@ namespace RoutingWebSite
|
||||||
// Set up application services
|
// Set up application services
|
||||||
public void ConfigureServices(IServiceCollection services)
|
public void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
|
var pageRouteTransformerConvention = new PageRouteTransformerConvention(new SlugifyParameterTransformer());
|
||||||
|
|
||||||
services
|
services
|
||||||
.AddMvc(options =>
|
.AddMvc(options =>
|
||||||
{
|
{
|
||||||
|
|
@ -23,6 +26,13 @@ namespace RoutingWebSite
|
||||||
typeof(ParameterTransformerController),
|
typeof(ParameterTransformerController),
|
||||||
new SlugifyParameterTransformer()));
|
new SlugifyParameterTransformer()));
|
||||||
})
|
})
|
||||||
|
.AddRazorPagesOptions(options =>
|
||||||
|
{
|
||||||
|
options.Conventions.AddFolderRouteModelConvention("/PageRouteTransformer", model =>
|
||||||
|
{
|
||||||
|
pageRouteTransformerConvention.Apply(model);
|
||||||
|
});
|
||||||
|
})
|
||||||
.SetCompatibilityVersion(CompatibilityVersion.Latest);
|
.SetCompatibilityVersion(CompatibilityVersion.Latest);
|
||||||
services
|
services
|
||||||
.AddRouting(options =>
|
.AddRouting(options =>
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
|
@ -13,8 +14,17 @@ namespace RoutingWebSite
|
||||||
{
|
{
|
||||||
public void ConfigureServices(IServiceCollection services)
|
public void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
|
var pageRouteTransformerConvention = new PageRouteTransformerConvention(new SlugifyParameterTransformer());
|
||||||
|
|
||||||
services
|
services
|
||||||
.AddMvc()
|
.AddMvc()
|
||||||
|
.AddRazorPagesOptions(options =>
|
||||||
|
{
|
||||||
|
options.Conventions.AddFolderRouteModelConvention("/PageRouteTransformer", model =>
|
||||||
|
{
|
||||||
|
pageRouteTransformerConvention.Apply(model);
|
||||||
|
});
|
||||||
|
})
|
||||||
.SetCompatibilityVersion(CompatibilityVersion.Latest);
|
.SetCompatibilityVersion(CompatibilityVersion.Latest);
|
||||||
services
|
services
|
||||||
.AddRouting(options =>
|
.AddRouting(options =>
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||||
|
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
||||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
using Microsoft.AspNetCore.Mvc.Controllers;
|
||||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
@ -19,8 +20,17 @@ namespace RoutingWebSite
|
||||||
// Set up application services
|
// Set up application services
|
||||||
public void ConfigureServices(IServiceCollection services)
|
public void ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
|
var pageRouteTransformerConvention = new PageRouteTransformerConvention(new SlugifyParameterTransformer());
|
||||||
|
|
||||||
services
|
services
|
||||||
.AddMvc()
|
.AddMvc()
|
||||||
|
.AddRazorPagesOptions(options =>
|
||||||
|
{
|
||||||
|
options.Conventions.AddFolderRouteModelConvention("/PageRouteTransformer", model =>
|
||||||
|
{
|
||||||
|
pageRouteTransformerConvention.Apply(model);
|
||||||
|
});
|
||||||
|
})
|
||||||
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
|
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
|
||||||
|
|
||||||
services.AddScoped<TestResponseGenerator>();
|
services.AddScoped<TestResponseGenerator>();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue