Make UseEndpoints a thing (#8765)
* Make endpoint middleware explicit This change makes the endpoint middleware explicit again, and updates all of the templates. The other change here is make UseEndpoints be the place where you register endpoints. This is vital because it puts your code visually at the point of the pipeline where it executes. Lastly, I removed support for UseMvc with endpoint routing. This is causing issues for some security features, and we're moving in the direction of trying to make the middleware heavy implementation required in 3.0. There are some issues we won't be able to fix in MVC if we can't unambiguously know if UseMvc was used or the middleware.
This commit is contained in:
parent
062cfac384
commit
658b37d2bd
|
|
@ -38,9 +38,18 @@ namespace AzureADB2CSample
|
|||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseHttpsRedirection();
|
||||
app.UseAuthentication();
|
||||
app.UseStaticFiles();
|
||||
app.UseMvcWithDefaultRoute();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
endpoints.MapRazorPages();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,9 +38,18 @@ namespace AzureADSample
|
|||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseHttpsRedirection();
|
||||
app.UseAuthentication();
|
||||
app.UseStaticFiles();
|
||||
app.UseMvcWithDefaultRoute();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
endpoints.MapRazorPages();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,16 @@ namespace AzureAD.WebSite
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseAuthentication();
|
||||
app.UseRouting();
|
||||
|
||||
app.UseMvc();
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
endpoints.MapRazorPages();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,9 +32,11 @@ namespace BlazorHosted_CSharp.Server
|
|||
app.UseBlazorDebugging();
|
||||
}
|
||||
|
||||
app.UseMvc(routes =>
|
||||
app.UseRouting();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapRoute(name: "default", template: "{controller}/{action}/{id?}");
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
});
|
||||
|
||||
app.UseBlazor<Client.Startup>();
|
||||
|
|
|
|||
|
|
@ -17,16 +17,16 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// the component <typeparamref name="TComponent"/> to this hub instance as the given DOM <paramref name="selector"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TComponent">The first <see cref="IComponent"/> associated with this <see cref="ComponentHub"/>.</typeparam>
|
||||
/// <param name="routes">The <see cref="RouteBuilder"/>.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/>.</param>
|
||||
/// <param name="selector">The selector for the <typeparamref name="TComponent"/>.</param>
|
||||
/// <returns>The <see cref="IEndpointConventionBuilder"/>.</returns>
|
||||
public static IEndpointConventionBuilder MapComponentHub<TComponent>(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string selector)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (selector == null)
|
||||
|
|
@ -34,7 +34,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(selector));
|
||||
}
|
||||
|
||||
return routes.MapComponentHub(typeof(TComponent), selector, ComponentHub.DefaultPath);
|
||||
return endpoints.MapComponentHub(typeof(TComponent), selector, ComponentHub.DefaultPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -42,18 +42,18 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// the component <typeparamref name="TComponent"/> to this hub instance as the given DOM <paramref name="selector"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="TComponent">The first <see cref="IComponent"/> associated with this <see cref="ComponentHub"/>.</typeparam>
|
||||
/// <param name="routes">The <see cref="RouteBuilder"/>.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/>.</param>
|
||||
/// <param name="selector">The selector for the <typeparamref name="TComponent"/>.</param>
|
||||
/// <param name="path">The path to map to which the <see cref="ComponentHub"/> will be mapped.</param>
|
||||
/// <returns>The <see cref="IEndpointConventionBuilder"/>.</returns>
|
||||
public static IEndpointConventionBuilder MapComponentHub<TComponent>(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string selector,
|
||||
string path)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (path == null)
|
||||
|
|
@ -66,27 +66,27 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(selector));
|
||||
}
|
||||
|
||||
return routes.MapComponentHub(typeof(TComponent), selector, path);
|
||||
return endpoints.MapComponentHub(typeof(TComponent), selector, path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps the SignalR <see cref="ComponentHub"/> to the path <paramref name="path"/> and associates
|
||||
/// the component <paramref name="componentType"/> to this hub instance as the given DOM <paramref name="selector"/>.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="RouteBuilder"/>.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/>.</param>
|
||||
/// <param name="componentType">The first <see cref="IComponent"/> associated with this <see cref="ComponentHub"/>.</param>
|
||||
/// <param name="selector">The selector for the <paramref name="componentType"/>.</param>
|
||||
/// <param name="path">The path to map to which the <see cref="ComponentHub"/> will be mapped.</param>
|
||||
/// <returns>The <see cref="IEndpointConventionBuilder"/>.</returns>
|
||||
public static IEndpointConventionBuilder MapComponentHub(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
Type componentType,
|
||||
string selector,
|
||||
string path)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (path == null)
|
||||
|
|
@ -104,7 +104,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(selector));
|
||||
}
|
||||
|
||||
return routes.MapHub<ComponentHub>(path).AddComponent(componentType, selector);
|
||||
return endpoints.MapHub<ComponentHub>(path).AddComponent(componentType, selector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ namespace Microsoft.AspNetCore.Components.Server.Circuits
|
|||
{
|
||||
throw new InvalidOperationException(
|
||||
$"{nameof(ComponentHub)} doesn't have an associated endpoint. " +
|
||||
"Use 'app.UseRouting(routes => routes.MapComponentHub<App>(\"app\"))' to register your hub.");
|
||||
"Use 'app.UseEndpoints(endpoints => endpoints.MapComponentHub<App>(\"app\"))' to register your hub.");
|
||||
}
|
||||
|
||||
var componentsMetadata = endpoint.Metadata.OfType<ComponentDescriptor>().ToList();
|
||||
|
|
|
|||
|
|
@ -29,10 +29,13 @@ namespace ComponentsApp.Server
|
|||
}
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.UseRouting(builder =>
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
builder.MapRazorPages();
|
||||
builder.MapComponentHub<App.App>("app");
|
||||
endpoints.MapRazorPages();
|
||||
endpoints.MapComponentHub<App.App>("app");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,24 +38,36 @@ namespace TestServer
|
|||
}
|
||||
|
||||
AllowCorsForAnyLocalhostPort(app);
|
||||
app.UseMvc();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
// Mount the server-side Blazor app on /subdir
|
||||
app.Map("/subdir", subdirApp =>
|
||||
{
|
||||
// The following two lines are equivalent to:
|
||||
// subdirApp.UseServerSideBlazor<BasicTestApp.Startup>();
|
||||
// However it's expressed using UseSignalR+UseBlazor as a way of checking that
|
||||
// we're not relying on any extra magic inside UseServerSideBlazor, since it's
|
||||
// endpoints.MapComponentsHub<Index>();
|
||||
//
|
||||
// However it's expressed using routing as a way of checking that
|
||||
// we're not relying on any extra magic inside MapComponentsHub, since it's
|
||||
// important that people can set up these bits of middleware manually (e.g., to
|
||||
// swap in UseAzureSignalR instead of UseSignalR).
|
||||
subdirApp.UseRouting(routes =>
|
||||
routes.MapHub<ComponentHub>(ComponentHub.DefaultPath).AddComponent<Index>(selector: "root"));
|
||||
|
||||
subdirApp.UseRouting();
|
||||
|
||||
subdirApp.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapHub<ComponentHub>(ComponentHub.DefaultPath).AddComponent<Index>(selector: "root");
|
||||
});
|
||||
|
||||
subdirApp.MapWhen(
|
||||
ctx => ctx.Features.Get<IEndpointFeature>()?.Endpoint == null,
|
||||
blazorBuilder => blazorBuilder.UseBlazor<BasicTestApp.Startup>());
|
||||
});
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
}
|
||||
|
||||
private static void AllowCorsForAnyLocalhostPort(IApplicationBuilder app)
|
||||
|
|
|
|||
|
|
@ -82,11 +82,17 @@ namespace Microsoft.AspNetCore.Builder.Internal
|
|||
{
|
||||
RequestDelegate app = context =>
|
||||
{
|
||||
// Implicitly execute matched endpoint at the end of the pipeline instead of returning 404
|
||||
var endpointRequestDelegate = context.GetEndpoint()?.RequestDelegate;
|
||||
// If we reach the end of the pipeline, but we have an endpoint, then something unexpected has happened.
|
||||
// This could happen if user code sets an endpoint, but they forgot to add the UseEndpoint middleware.
|
||||
var endpoint = context.GetEndpoint();
|
||||
var endpointRequestDelegate = endpoint?.RequestDelegate;
|
||||
if (endpointRequestDelegate != null)
|
||||
{
|
||||
return endpointRequestDelegate(context);
|
||||
var message =
|
||||
$"The request reached the end of the pipeline without executing the endpoint: '{endpoint.DisplayName}'. " +
|
||||
$"Please register the EndpointMiddleware using '{nameof(IApplicationBuilder)}.UseEndpoints(...)' if using " +
|
||||
$"routing, or '{nameof(IApplicationBuilder)}.UseEndpointExecutor()' if not using routing.";
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
||||
context.Response.StatusCode = 404;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// 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.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Endpoints;
|
||||
|
|
@ -23,7 +24,7 @@ namespace Microsoft.AspNetCore.Builder.Internal
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void BuildImplicitlyCallsMatchedEndpointAsLastStep()
|
||||
public async Task BuildImplicitlyThrowsForMatchedEndpointAsLastStep()
|
||||
{
|
||||
var builder = new ApplicationBuilder(null);
|
||||
var app = builder.Build();
|
||||
|
|
@ -41,9 +42,14 @@ namespace Microsoft.AspNetCore.Builder.Internal
|
|||
var httpContext = new DefaultHttpContext();
|
||||
httpContext.SetEndpoint(endpoint);
|
||||
|
||||
app.Invoke(httpContext);
|
||||
var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => app.Invoke(httpContext));
|
||||
|
||||
Assert.True(endpointCalled);
|
||||
var expected =
|
||||
"The request reached the end of the pipeline without executing the endpoint: 'Test endpoint'. " +
|
||||
"Please register the EndpointMiddleware using 'IApplicationBuilder.UseEndpoints(...)' if " +
|
||||
"using routing, or 'IApplicationBuilder.UseEndpointExecutor()' if not using routing.";
|
||||
Assert.Equal(expected, ex.Message);
|
||||
Assert.False(endpointCalled);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -87,4 +93,4 @@ namespace Microsoft.AspNetCore.Builder.Internal
|
|||
Assert.Equal("value1", builder1.Properties["test"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,23 +5,24 @@ namespace Microsoft.AspNetCore.Builder
|
|||
{
|
||||
public static partial class EndpointRouteBuilderExtensions
|
||||
{
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder Map(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, Microsoft.AspNetCore.Routing.Patterns.RoutePattern pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder Map(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapDelete(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapGet(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapMethods(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, System.Collections.Generic.IEnumerable<string> httpMethods, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapPost(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapPut(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder Map(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, Microsoft.AspNetCore.Routing.Patterns.RoutePattern pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder Map(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapDelete(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapGet(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapMethods(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string pattern, System.Collections.Generic.IEnumerable<string> httpMethods, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapPost(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapPut(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
|
||||
}
|
||||
public static partial class EndpointRoutingApplicationBuilderExtensions
|
||||
{
|
||||
public static Microsoft.AspNetCore.Builder.IApplicationBuilder UseEndpoint(this Microsoft.AspNetCore.Builder.IApplicationBuilder builder) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IApplicationBuilder UseRouting(this Microsoft.AspNetCore.Builder.IApplicationBuilder builder, System.Action<Microsoft.AspNetCore.Routing.IEndpointRouteBuilder> configure) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IApplicationBuilder UseEndpointExecutor(this Microsoft.AspNetCore.Builder.IApplicationBuilder builder) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IApplicationBuilder UseEndpoints(this Microsoft.AspNetCore.Builder.IApplicationBuilder builder, System.Action<Microsoft.AspNetCore.Routing.IEndpointRouteBuilder> configure) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IApplicationBuilder UseRouting(this Microsoft.AspNetCore.Builder.IApplicationBuilder builder) { throw null; }
|
||||
}
|
||||
public static partial class FallbackEndpointRouteBuilderExtensions
|
||||
{
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapFallback(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapFallback(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapFallback(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapFallback(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string pattern, Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { throw null; }
|
||||
}
|
||||
public static partial class MapRouteRouteBuilderExtensions
|
||||
{
|
||||
|
|
|
|||
|
|
@ -26,77 +26,77 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// Adds a <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that matches HTTP GET requests
|
||||
/// for the specified pattern.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="pattern">The route pattern.</param>
|
||||
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
|
||||
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
|
||||
public static IEndpointConventionBuilder MapGet(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string pattern,
|
||||
RequestDelegate requestDelegate)
|
||||
{
|
||||
return MapMethods(routes, pattern, GetVerb, requestDelegate);
|
||||
return MapMethods(endpoints, pattern, GetVerb, requestDelegate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that matches HTTP POST requests
|
||||
/// for the specified pattern.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="pattern">The route pattern.</param>
|
||||
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
|
||||
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
|
||||
public static IEndpointConventionBuilder MapPost(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string pattern,
|
||||
RequestDelegate requestDelegate)
|
||||
{
|
||||
return MapMethods(routes, pattern, PostVerb, requestDelegate);
|
||||
return MapMethods(endpoints, pattern, PostVerb, requestDelegate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that matches HTTP PUT requests
|
||||
/// for the specified pattern.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="pattern">The route pattern.</param>
|
||||
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
|
||||
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
|
||||
public static IEndpointConventionBuilder MapPut(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string pattern,
|
||||
RequestDelegate requestDelegate)
|
||||
{
|
||||
return MapMethods(routes, pattern, PutVerb, requestDelegate);
|
||||
return MapMethods(endpoints, pattern, PutVerb, requestDelegate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that matches HTTP DELETE requests
|
||||
/// for the specified pattern.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="pattern">The route pattern.</param>
|
||||
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
|
||||
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
|
||||
public static IEndpointConventionBuilder MapDelete(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string pattern,
|
||||
RequestDelegate requestDelegate)
|
||||
{
|
||||
return MapMethods(routes, pattern, DeleteVerb, requestDelegate);
|
||||
return MapMethods(endpoints, pattern, DeleteVerb, requestDelegate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that matches HTTP requests
|
||||
/// for the specified HTTP methods and pattern.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="pattern">The route pattern.</param>
|
||||
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
|
||||
/// <param name="httpMethods">HTTP methods that the endpoint will match.</param>
|
||||
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
|
||||
public static IEndpointConventionBuilder MapMethods(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string pattern,
|
||||
IEnumerable<string> httpMethods,
|
||||
RequestDelegate requestDelegate)
|
||||
|
|
@ -106,7 +106,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(httpMethods));
|
||||
}
|
||||
|
||||
var builder = routes.Map(RoutePatternFactory.Parse(pattern), requestDelegate);
|
||||
var builder = endpoints.Map(RoutePatternFactory.Parse(pattern), requestDelegate);
|
||||
builder.WithDisplayName($"{pattern} HTTP: {string.Join(", ", httpMethods)}");
|
||||
builder.WithMetadata(new HttpMethodMetadata(httpMethods));
|
||||
return builder;
|
||||
|
|
@ -116,34 +116,34 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// Adds a <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that matches HTTP requests
|
||||
/// for the specified pattern.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="pattern">The route pattern.</param>
|
||||
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
|
||||
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
|
||||
public static IEndpointConventionBuilder Map(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string pattern,
|
||||
RequestDelegate requestDelegate)
|
||||
{
|
||||
return Map(routes, RoutePatternFactory.Parse(pattern), requestDelegate);
|
||||
return Map(endpoints, RoutePatternFactory.Parse(pattern), requestDelegate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that matches HTTP requests
|
||||
/// for the specified pattern.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="pattern">The route pattern.</param>
|
||||
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
|
||||
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
|
||||
public static IEndpointConventionBuilder Map(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
RoutePattern pattern,
|
||||
RequestDelegate requestDelegate)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (pattern == null)
|
||||
|
|
@ -178,11 +178,11 @@ namespace Microsoft.AspNetCore.Builder
|
|||
}
|
||||
}
|
||||
|
||||
var dataSource = routes.DataSources.OfType<ModelEndpointDataSource>().FirstOrDefault();
|
||||
var dataSource = endpoints.DataSources.OfType<ModelEndpointDataSource>().FirstOrDefault();
|
||||
if (dataSource == null)
|
||||
{
|
||||
dataSource = new ModelEndpointDataSource();
|
||||
routes.DataSources.Add(dataSource);
|
||||
endpoints.DataSources.Add(dataSource);
|
||||
}
|
||||
|
||||
return dataSource.AddEndpointBuilder(builder);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Routing.Internal;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
|
@ -11,17 +12,66 @@ namespace Microsoft.AspNetCore.Builder
|
|||
{
|
||||
public static class EndpointRoutingApplicationBuilderExtensions
|
||||
{
|
||||
// Property key is used by MVC package to check that routing is registered
|
||||
private const string EndpointRoutingRegisteredKey = "__EndpointRoutingMiddlewareRegistered";
|
||||
private const string EndpointRouteBuilder = "__EndpointRouteBuilder";
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="EndpointRoutingMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>
|
||||
/// Adds a <see cref="EndpointRoutingMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// A call to <see cref="UseRouting(IApplicationBuilder)"/> must be followed by a call to
|
||||
/// <see cref="UseEndpoints(IApplicationBuilder, Action{IEndpointRouteBuilder})"/> for the same <see cref="IApplicationBuilder"/>
|
||||
/// instance.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The <see cref="EndpointRoutingMiddleware"/> defines a point in the middleware pipeline where routing decisions are
|
||||
/// made, and an <see cref="Endpoint"/> is associated with the <see cref="HttpContext"/>. The <see cref="EndpointMiddleware"/>
|
||||
/// defines a point in the middleware pipeline where the current <see cref="Endpoint"/> is executed. Middleware between
|
||||
/// the <see cref="EndpointRoutingMiddleware"/> and <see cref="EndpointMiddleware"/> may observe or change the
|
||||
/// <see cref="Endpoint"/> associated with the <see cref="HttpContext"/>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IApplicationBuilder UseRouting(this IApplicationBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
VerifyRoutingServicesAreRegistered(builder);
|
||||
|
||||
var endpointRouteBuilder = new DefaultEndpointRouteBuilder(builder);
|
||||
builder.Properties[EndpointRouteBuilder] = endpointRouteBuilder;
|
||||
|
||||
return builder.UseMiddleware<EndpointRoutingMiddleware>(endpointRouteBuilder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="EndpointMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>
|
||||
/// with the <see cref="EndpointDataSource"/> instances built from configured <see cref="IEndpointRouteBuilder"/>.
|
||||
/// The <see cref="EndpointMiddleware"/> will execute the <see cref="Endpoint"/> associated with the current
|
||||
/// request.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="configure">An <see cref="Action{IEndpointRouteBuilder}"/> to configure the provided <see cref="IEndpointRouteBuilder"/>.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
public static IApplicationBuilder UseRouting(this IApplicationBuilder builder, Action<IEndpointRouteBuilder> configure)
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// A call to <see cref="UseEndpoints(IApplicationBuilder, Action{IEndpointRouteBuilder})"/> must be preceded by a call to
|
||||
/// <see cref="UseRouting(IApplicationBuilder)"/> for the same <see cref="IApplicationBuilder"/>
|
||||
/// instance.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The <see cref="EndpointRoutingMiddleware"/> defines a point in the middleware pipeline where routing decisions are
|
||||
/// made, and an <see cref="Endpoint"/> is associated with the <see cref="HttpContext"/>. The <see cref="EndpointMiddleware"/>
|
||||
/// defines a point in the middleware pipeline where the current <see cref="Endpoint"/> is executed. Middleware between
|
||||
/// the <see cref="EndpointRoutingMiddleware"/> and <see cref="EndpointMiddleware"/> may observe or change the
|
||||
/// <see cref="Endpoint"/> associated with the <see cref="HttpContext"/>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IApplicationBuilder UseEndpoints(this IApplicationBuilder builder, Action<IEndpointRouteBuilder> configure)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
|
|
@ -33,57 +83,52 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(configure));
|
||||
}
|
||||
|
||||
VerifyRoutingIsRegistered(builder);
|
||||
VerifyRoutingServicesAreRegistered(builder);
|
||||
|
||||
var routeOptions = builder.ApplicationServices.GetRequiredService<IOptions<RouteOptions>>();
|
||||
EndpointDataSource middlewareEndpointDataSource;
|
||||
VerifyEndpointRoutingMiddlewareIsRegistered(builder, out var endpointRouteBuilder);
|
||||
|
||||
var endpointRouteBuilder = builder.ApplicationServices.GetRequiredService<IEndpointRouteBuilder>();
|
||||
if (endpointRouteBuilder is DefaultEndpointRouteBuilder defaultEndpointRouteBuilder)
|
||||
{
|
||||
defaultEndpointRouteBuilder.ApplicationBuilder = builder;
|
||||
}
|
||||
configure(endpointRouteBuilder);
|
||||
|
||||
// Yes, this mutates an IOptions. We're registering data sources in a global collection which
|
||||
// can be used for discovery of endpoints or URL generation.
|
||||
//
|
||||
// Each middleware gets its own collection of data sources, and all of those data sources also
|
||||
// get added to a global collection.
|
||||
var routeOptions = builder.ApplicationServices.GetRequiredService<IOptions<RouteOptions>>();
|
||||
foreach (var dataSource in endpointRouteBuilder.DataSources)
|
||||
{
|
||||
routeOptions.Value.EndpointDataSources.Add(dataSource);
|
||||
}
|
||||
|
||||
// Create endpoint data source for data sources registered in configure
|
||||
middlewareEndpointDataSource = new CompositeEndpointDataSource(endpointRouteBuilder.DataSources);
|
||||
|
||||
builder.Properties[EndpointRoutingRegisteredKey] = true;
|
||||
|
||||
return builder.UseMiddleware<EndpointRoutingMiddleware>(middlewareEndpointDataSource);
|
||||
return builder.UseMiddleware<EndpointMiddleware>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a <see cref="EndpointMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>.
|
||||
/// Adds a <see cref="EndpointMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/> that will
|
||||
/// execute the <see cref="Endpoint"/> associated with the current request.
|
||||
/// </summary>
|
||||
/// <param name="builder">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
public static IApplicationBuilder UseEndpoint(this IApplicationBuilder builder)
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// A call to <see cref="UseEndpointExecutor(IApplicationBuilder)"/> may be used to execute an endpoint with
|
||||
/// using <see cref="UseRouting(IApplicationBuilder)" />. This enables applications to use endpoints with other
|
||||
/// middleware not related to routing.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IApplicationBuilder UseEndpointExecutor(this IApplicationBuilder builder)
|
||||
{
|
||||
if (builder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(builder));
|
||||
}
|
||||
|
||||
VerifyRoutingIsRegistered(builder);
|
||||
|
||||
if (!builder.Properties.TryGetValue(EndpointRoutingRegisteredKey, out _))
|
||||
{
|
||||
var message = $"{nameof(EndpointRoutingMiddleware)} must be added to the request execution pipeline before {nameof(EndpointMiddleware)}. " +
|
||||
$"Please add {nameof(EndpointRoutingMiddleware)} by calling '{nameof(IApplicationBuilder)}.{nameof(UseRouting)}' inside the call to 'Configure(...)' in the application startup code.";
|
||||
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
// Note: we don't require routing services either.
|
||||
|
||||
return builder.UseMiddleware<EndpointMiddleware>();
|
||||
}
|
||||
|
||||
private static void VerifyRoutingIsRegistered(IApplicationBuilder app)
|
||||
private static void VerifyRoutingServicesAreRegistered(IApplicationBuilder app)
|
||||
{
|
||||
// Verify if AddRouting was done before calling UseEndpointRouting/UseEndpoint
|
||||
// We use the RoutingMarkerService to make sure if all the services were added.
|
||||
|
|
@ -95,5 +140,32 @@ namespace Microsoft.AspNetCore.Builder
|
|||
"ConfigureServices(...)"));
|
||||
}
|
||||
}
|
||||
|
||||
private static void VerifyEndpointRoutingMiddlewareIsRegistered(IApplicationBuilder app, out DefaultEndpointRouteBuilder endpointRouteBuilder)
|
||||
{
|
||||
if (!app.Properties.TryGetValue(EndpointRouteBuilder, out var obj))
|
||||
{
|
||||
var message =
|
||||
$"{nameof(EndpointRoutingMiddleware)} matches endpoints setup by {nameof(EndpointMiddleware)} and so must be added to the request " +
|
||||
$"execution pipeline before {nameof(EndpointMiddleware)}. " +
|
||||
$"Please add {nameof(EndpointRoutingMiddleware)} by calling '{nameof(IApplicationBuilder)}.{nameof(UseRouting)}' inside the call " +
|
||||
$"to 'Configure(...)' in the application startup code.";
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
|
||||
// If someone messes with this, just let it crash.
|
||||
endpointRouteBuilder = (DefaultEndpointRouteBuilder)obj;
|
||||
|
||||
// This check handles the case where Map or something else that forks the pipeline is called between the two
|
||||
// routing middleware.
|
||||
if (!object.ReferenceEquals(app, endpointRouteBuilder.ApplicationBuilder))
|
||||
{
|
||||
var message =
|
||||
$"The {nameof(EndpointRoutingMiddleware)} and {nameof(EndpointMiddleware)} must be added to the same {nameof(IApplicationBuilder)} instance. " +
|
||||
$"To use Endpoint Routing with 'Map(...)', make sure to call '{nameof(IApplicationBuilder)}.{nameof(UseRouting)}' before " +
|
||||
$"'{nameof(IApplicationBuilder)}.{nameof(UseEndpoints)}' for each branch of the middleware pipeline.";
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// Adds a specialized <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that will match
|
||||
/// requests for non-file-names with the lowest possible priority.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
|
||||
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
|
||||
/// <remarks>
|
||||
|
|
@ -31,11 +31,11 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// <c>{*path:nonfile}</c>. The order of the registered endpoint will be <c>int.MaxValue</c>.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static IEndpointConventionBuilder MapFallback(this IEndpointRouteBuilder routes, RequestDelegate requestDelegate)
|
||||
public static IEndpointConventionBuilder MapFallback(this IEndpointRouteBuilder endpoints, RequestDelegate requestDelegate)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (requestDelegate == null)
|
||||
|
|
@ -43,14 +43,14 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(requestDelegate));
|
||||
}
|
||||
|
||||
return routes.MapFallback("{*path:nonfile}", requestDelegate);
|
||||
return endpoints.MapFallback("{*path:nonfile}", requestDelegate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a specialized <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that will match
|
||||
/// the provided pattern with the lowest possible priority.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="pattern">The route pattern.</param>
|
||||
/// <param name="requestDelegate">The delegate executed when the endpoint is matched.</param>
|
||||
/// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
|
||||
|
|
@ -68,13 +68,13 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </para>
|
||||
/// </remarks>
|
||||
public static IEndpointConventionBuilder MapFallback(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string pattern,
|
||||
RequestDelegate requestDelegate)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (pattern == null)
|
||||
|
|
@ -87,7 +87,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(requestDelegate));
|
||||
}
|
||||
|
||||
var conventionBuilder = routes.Map(pattern, requestDelegate);
|
||||
var conventionBuilder = endpoints.Map(pattern, requestDelegate);
|
||||
conventionBuilder.WithDisplayName("Fallback " + pattern);
|
||||
conventionBuilder.Add(b => ((RouteEndpointBuilder)b).Order = int.MaxValue);
|
||||
return conventionBuilder;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// 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;
|
||||
|
|
@ -9,12 +9,13 @@ namespace Microsoft.AspNetCore.Routing
|
|||
{
|
||||
internal class DefaultEndpointRouteBuilder : IEndpointRouteBuilder
|
||||
{
|
||||
public DefaultEndpointRouteBuilder()
|
||||
public DefaultEndpointRouteBuilder(IApplicationBuilder applicationBuilder)
|
||||
{
|
||||
ApplicationBuilder = applicationBuilder ?? throw new ArgumentNullException(nameof(applicationBuilder));
|
||||
DataSources = new List<EndpointDataSource>();
|
||||
}
|
||||
|
||||
public IApplicationBuilder ApplicationBuilder { get; set; }
|
||||
public IApplicationBuilder ApplicationBuilder { get; }
|
||||
|
||||
public IApplicationBuilder CreateApplicationBuilder() => ApplicationBuilder.New();
|
||||
|
||||
|
|
@ -22,4 +23,4 @@ namespace Microsoft.AspNetCore.Routing
|
|||
|
||||
public IServiceProvider ServiceProvider => ApplicationBuilder.ApplicationServices;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,11 +64,6 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
return new CompositeEndpointDataSource(dataSources);
|
||||
});
|
||||
|
||||
//
|
||||
// Endpoint Infrastructure
|
||||
//
|
||||
services.TryAddTransient<IEndpointRouteBuilder, DefaultEndpointRouteBuilder>();
|
||||
|
||||
//
|
||||
// Default matcher implementation
|
||||
//
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// 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;
|
||||
|
|
@ -8,7 +8,6 @@ using Microsoft.AspNetCore.Http;
|
|||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Routing.Matching;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Microsoft.AspNetCore.Routing
|
||||
{
|
||||
|
|
@ -23,8 +22,8 @@ namespace Microsoft.AspNetCore.Routing
|
|||
|
||||
public EndpointRoutingMiddleware(
|
||||
MatcherFactory matcherFactory,
|
||||
EndpointDataSource endpointDataSource,
|
||||
ILogger<EndpointRoutingMiddleware> logger,
|
||||
IEndpointRouteBuilder endpointRouteBuilder,
|
||||
RequestDelegate next)
|
||||
{
|
||||
if (matcherFactory == null)
|
||||
|
|
@ -32,25 +31,26 @@ namespace Microsoft.AspNetCore.Routing
|
|||
throw new ArgumentNullException(nameof(matcherFactory));
|
||||
}
|
||||
|
||||
if (endpointDataSource == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(endpointDataSource));
|
||||
}
|
||||
|
||||
if (logger == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
if (endpointRouteBuilder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(endpointRouteBuilder));
|
||||
}
|
||||
|
||||
if (next == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(next));
|
||||
}
|
||||
|
||||
_matcherFactory = matcherFactory;
|
||||
_endpointDataSource = endpointDataSource;
|
||||
_logger = logger;
|
||||
_next = next;
|
||||
|
||||
_endpointDataSource = new CompositeEndpointDataSource(endpointRouteBuilder.DataSources);
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext httpContext)
|
||||
|
|
@ -165,4 +165,4 @@ namespace Microsoft.AspNetCore.Routing
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,13 +6,13 @@ using System.Collections.Generic;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder.Internal;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Endpoints;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Routing.Matching;
|
||||
using Microsoft.AspNetCore.Routing.Patterns;
|
||||
using Microsoft.AspNetCore.Routing.TestObjects;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
var app = new ApplicationBuilder(Mock.Of<IServiceProvider>());
|
||||
|
||||
// Act
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => app.UseRouting(builder => { }));
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => app.UseRouting());
|
||||
|
||||
// Assert
|
||||
Assert.Equal(
|
||||
|
|
@ -44,7 +44,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
var app = new ApplicationBuilder(Mock.Of<IServiceProvider>());
|
||||
|
||||
// Act
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => app.UseEndpoint());
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => app.UseEndpoints(endpoints => { }));
|
||||
|
||||
// Assert
|
||||
Assert.Equal(
|
||||
|
|
@ -62,7 +62,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
|
||||
var app = new ApplicationBuilder(services);
|
||||
|
||||
app.UseRouting(builder => { });
|
||||
app.UseRouting();
|
||||
|
||||
var appFunc = app.Build();
|
||||
var httpContext = new DefaultHttpContext();
|
||||
|
|
@ -89,9 +89,11 @@ namespace Microsoft.AspNetCore.Builder
|
|||
|
||||
var app = new ApplicationBuilder(services);
|
||||
|
||||
app.UseRouting(builder =>
|
||||
app.UseRouting();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
builder.DataSources.Add(new DefaultEndpointDataSource(endpoint));
|
||||
endpoints.DataSources.Add(new DefaultEndpointDataSource(endpoint));
|
||||
});
|
||||
|
||||
var appFunc = app.Build();
|
||||
|
|
@ -107,7 +109,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void UseEndpoint_WithoutRoutingServicesRegistered_Throws()
|
||||
public void UseEndpoint_WithoutEndpointRoutingMiddleware_Throws()
|
||||
{
|
||||
// Arrange
|
||||
var services = CreateServices();
|
||||
|
|
@ -115,16 +117,38 @@ namespace Microsoft.AspNetCore.Builder
|
|||
var app = new ApplicationBuilder(services);
|
||||
|
||||
// Act
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => app.UseEndpoint());
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => app.UseEndpoints(endpoints => { }));
|
||||
|
||||
// Assert
|
||||
Assert.Equal(
|
||||
"EndpointRoutingMiddleware must be added to the request execution pipeline before EndpointMiddleware. " +
|
||||
"EndpointRoutingMiddleware matches endpoints setup by EndpointMiddleware and so must be added to the request " +
|
||||
"execution pipeline before EndpointMiddleware. " +
|
||||
"Please add EndpointRoutingMiddleware by calling 'IApplicationBuilder.UseRouting' " +
|
||||
"inside the call to 'Configure(...)' in the application startup code.",
|
||||
ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UseEndpoint_WithApplicationBuilderMismatch_Throws()
|
||||
{
|
||||
// Arrange
|
||||
var services = CreateServices();
|
||||
|
||||
var app = new ApplicationBuilder(services);
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
// Act
|
||||
var ex = Assert.Throws<InvalidOperationException>(() => app.Map("/Test", b => b.UseEndpoints(endpoints => { })));
|
||||
|
||||
// Assert
|
||||
Assert.Equal(
|
||||
"The EndpointRoutingMiddleware and EndpointMiddleware must be added to the same IApplicationBuilder instance. " +
|
||||
"To use Endpoint Routing with 'Map(...)', make sure to call 'IApplicationBuilder.UseRouting' before " +
|
||||
"'IApplicationBuilder.UseEndpoints' for each branch of the middleware pipeline.",
|
||||
ex.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UseEndpoint_ServicesRegisteredAndEndpointRoutingRegistered_NoMatch_DoesNotSetFeature()
|
||||
{
|
||||
|
|
@ -133,8 +157,8 @@ namespace Microsoft.AspNetCore.Builder
|
|||
|
||||
var app = new ApplicationBuilder(services);
|
||||
|
||||
app.UseRouting(builder => { });
|
||||
app.UseEndpoint();
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints => { });
|
||||
|
||||
var appFunc = app.Build();
|
||||
var httpContext = new DefaultHttpContext();
|
||||
|
|
@ -147,7 +171,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void UseRouting_CallWithBuilder_SetsEndpointDataSource()
|
||||
public void UseEndpoints_CallWithBuilder_SetsEndpointDataSource()
|
||||
{
|
||||
// Arrange
|
||||
var matcherEndpointDataSources = new List<EndpointDataSource>();
|
||||
|
|
@ -165,13 +189,15 @@ namespace Microsoft.AspNetCore.Builder
|
|||
var app = new ApplicationBuilder(services);
|
||||
|
||||
// Act
|
||||
app.UseRouting(builder =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(builder =>
|
||||
{
|
||||
builder.Map("/1", d => null).WithDisplayName("Test endpoint 1");
|
||||
builder.Map("/2", d => null).WithDisplayName("Test endpoint 2");
|
||||
});
|
||||
|
||||
app.UseRouting(builder =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(builder =>
|
||||
{
|
||||
builder.Map("/3", d => null).WithDisplayName("Test endpoint 3");
|
||||
builder.Map("/4", d => null).WithDisplayName("Test endpoint 4");
|
||||
|
|
@ -185,16 +211,83 @@ namespace Microsoft.AspNetCore.Builder
|
|||
// Assert
|
||||
Assert.Equal(2, matcherEndpointDataSources.Count);
|
||||
|
||||
// Each middleware has its own endpoints
|
||||
// each UseRouter has its own data source collection
|
||||
Assert.Collection(matcherEndpointDataSources[0].Endpoints,
|
||||
e => Assert.Equal("Test endpoint 1", e.DisplayName),
|
||||
e => Assert.Equal("Test endpoint 2", e.DisplayName));
|
||||
|
||||
Assert.Collection(matcherEndpointDataSources[1].Endpoints,
|
||||
e => Assert.Equal("Test endpoint 3", e.DisplayName),
|
||||
e => Assert.Equal("Test endpoint 4", e.DisplayName));
|
||||
|
||||
var compositeEndpointBuilder = services.GetRequiredService<EndpointDataSource>();
|
||||
|
||||
// Global collection has all endpoints
|
||||
Assert.Collection(compositeEndpointBuilder.Endpoints,
|
||||
e => Assert.Equal("Test endpoint 1", e.DisplayName),
|
||||
e => Assert.Equal("Test endpoint 2", e.DisplayName),
|
||||
e => Assert.Equal("Test endpoint 3", e.DisplayName),
|
||||
e => Assert.Equal("Test endpoint 4", e.DisplayName));
|
||||
}
|
||||
|
||||
// Verifies that it's possible to use endpoints and map together.
|
||||
[Fact]
|
||||
public void UseEndpoints_CallWithBuilder_SetsEndpointDataSource_WithMap()
|
||||
{
|
||||
// Arrange
|
||||
var matcherEndpointDataSources = new List<EndpointDataSource>();
|
||||
var matcherFactoryMock = new Mock<MatcherFactory>();
|
||||
matcherFactoryMock
|
||||
.Setup(m => m.CreateMatcher(It.IsAny<EndpointDataSource>()))
|
||||
.Callback((EndpointDataSource arg) =>
|
||||
{
|
||||
matcherEndpointDataSources.Add(arg);
|
||||
})
|
||||
.Returns(new TestMatcher(false));
|
||||
|
||||
var services = CreateServices(matcherFactoryMock.Object);
|
||||
|
||||
var app = new ApplicationBuilder(services);
|
||||
|
||||
// Act
|
||||
app.UseRouting();
|
||||
|
||||
app.Map("/foo", b =>
|
||||
{
|
||||
b.UseRouting();
|
||||
b.UseEndpoints(builder =>
|
||||
{
|
||||
builder.Map("/1", d => null).WithDisplayName("Test endpoint 1");
|
||||
builder.Map("/2", d => null).WithDisplayName("Test endpoint 2");
|
||||
});
|
||||
});
|
||||
|
||||
app.UseEndpoints(builder =>
|
||||
{
|
||||
builder.Map("/3", d => null).WithDisplayName("Test endpoint 3");
|
||||
builder.Map("/4", d => null).WithDisplayName("Test endpoint 4");
|
||||
});
|
||||
|
||||
// This triggers the middleware to be created and the matcher factory to be called
|
||||
// with the datasource we want to test
|
||||
var requestDelegate = app.Build();
|
||||
requestDelegate(new DefaultHttpContext());
|
||||
requestDelegate(new DefaultHttpContext() { Request = { Path = "/Foo", }, });
|
||||
|
||||
// Assert
|
||||
Assert.Equal(2, matcherEndpointDataSources.Count);
|
||||
|
||||
// Each UseRouter has its own data source
|
||||
Assert.Collection(matcherEndpointDataSources[1].Endpoints, // app.UseRouter
|
||||
e => Assert.Equal("Test endpoint 1", e.DisplayName),
|
||||
e => Assert.Equal("Test endpoint 2", e.DisplayName));
|
||||
|
||||
Assert.Collection(matcherEndpointDataSources[0].Endpoints, // b.UseRouter
|
||||
e => Assert.Equal("Test endpoint 3", e.DisplayName),
|
||||
e => Assert.Equal("Test endpoint 4", e.DisplayName));
|
||||
|
||||
var compositeEndpointBuilder = services.GetRequiredService<EndpointDataSource>();
|
||||
|
||||
// Global middleware has all endpoints
|
||||
Assert.Collection(compositeEndpointBuilder.Endpoints,
|
||||
e => Assert.Equal("Test endpoint 1", e.DisplayName),
|
||||
|
|
@ -203,6 +296,37 @@ namespace Microsoft.AspNetCore.Builder
|
|||
e => Assert.Equal("Test endpoint 4", e.DisplayName));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UseEndpointExecutor_RunsEndpoint()
|
||||
{
|
||||
// Arrange
|
||||
var services = CreateServices();
|
||||
|
||||
var endpointRan = false;
|
||||
var app = new ApplicationBuilder(services);
|
||||
|
||||
app.Use(next => context =>
|
||||
{
|
||||
context.SetEndpoint(new Endpoint(c =>
|
||||
{
|
||||
endpointRan = true;
|
||||
return Task.CompletedTask;
|
||||
}, new EndpointMetadataCollection(), "Test"));
|
||||
return next(context);
|
||||
});
|
||||
|
||||
app.UseEndpointExecutor(); // No services required, no UseRouting required
|
||||
|
||||
var appFunc = app.Build();
|
||||
var httpContext = new DefaultHttpContext();
|
||||
|
||||
// Act
|
||||
await appFunc(httpContext);
|
||||
|
||||
// Assert
|
||||
Assert.True(endpointRan);
|
||||
}
|
||||
|
||||
private IServiceProvider CreateServices()
|
||||
{
|
||||
return CreateServices(matcherFactory: null);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ using System.Threading.Tasks;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.AspNetCore.Routing.Patterns;
|
||||
using Moq;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Builder
|
||||
|
|
@ -29,7 +30,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
public void MapEndpoint_StringPattern_BuildsEndpoint()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultEndpointRouteBuilder();
|
||||
var builder = new DefaultEndpointRouteBuilder(Mock.Of<IApplicationBuilder>());
|
||||
RequestDelegate requestDelegate = (d) => null;
|
||||
|
||||
// Act
|
||||
|
|
@ -47,7 +48,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
public void MapEndpoint_TypedPattern_BuildsEndpoint()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultEndpointRouteBuilder();
|
||||
var builder = new DefaultEndpointRouteBuilder(Mock.Of<IApplicationBuilder>());
|
||||
RequestDelegate requestDelegate = (d) => null;
|
||||
|
||||
// Act
|
||||
|
|
@ -65,7 +66,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
public void MapEndpoint_AttributesCollectedAsMetadata()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultEndpointRouteBuilder();
|
||||
var builder = new DefaultEndpointRouteBuilder(Mock.Of<IApplicationBuilder>());
|
||||
|
||||
// Act
|
||||
var endpointBuilder = builder.Map(RoutePatternFactory.Parse("/"), Handle);
|
||||
|
|
@ -82,7 +83,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
public void MapEndpoint_GeneratedDelegateWorks()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultEndpointRouteBuilder();
|
||||
var builder = new DefaultEndpointRouteBuilder(Mock.Of<IApplicationBuilder>());
|
||||
|
||||
Expression<RequestDelegate> handler = context => Task.CompletedTask;
|
||||
|
||||
|
|
@ -98,7 +99,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
public void MapEndpoint_PrecedenceOfMetadata_BuilderMetadataReturned()
|
||||
{
|
||||
// Arrange
|
||||
var builder = new DefaultEndpointRouteBuilder();
|
||||
var builder = new DefaultEndpointRouteBuilder(Mock.Of<IApplicationBuilder>());
|
||||
|
||||
// Act
|
||||
var endpointBuilder = builder.MapMethods("/", new[] { "METHOD" }, HandleHttpMetdata);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Routing.Matching;
|
||||
|
|
@ -153,8 +154,8 @@ namespace Microsoft.AspNetCore.Routing
|
|||
|
||||
var middleware = new EndpointRoutingMiddleware(
|
||||
matcherFactory,
|
||||
new DefaultEndpointDataSource(),
|
||||
logger,
|
||||
new DefaultEndpointRouteBuilder(Mock.Of<IApplicationBuilder>()),
|
||||
next);
|
||||
|
||||
return middleware;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// 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.Text;
|
||||
|
|
@ -21,7 +21,9 @@ namespace Benchmarks
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRouting(builder =>
|
||||
app.UseRouting();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
var endpointDataSource = new DefaultEndpointDataSource(new[]
|
||||
{
|
||||
|
|
@ -41,10 +43,8 @@ namespace Benchmarks
|
|||
displayName: "Plaintext"),
|
||||
});
|
||||
|
||||
builder.DataSources.Add(endpointDataSource);
|
||||
endpoints.DataSources.Add(endpointDataSource);
|
||||
});
|
||||
|
||||
app.UseEndpoint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// 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;
|
||||
|
|
@ -15,23 +15,23 @@ namespace RoutingSandbox.Framework
|
|||
{
|
||||
public static class FrameworkEndpointRouteBuilderExtensions
|
||||
{
|
||||
public static IEndpointConventionBuilder MapFramework(this IEndpointRouteBuilder routes, Action<FrameworkConfigurationBuilder> configure)
|
||||
public static IEndpointConventionBuilder MapFramework(this IEndpointRouteBuilder endpoints, Action<FrameworkConfigurationBuilder> configure)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
if (configure == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(configure));
|
||||
}
|
||||
|
||||
var dataSource = routes.ServiceProvider.GetRequiredService<FrameworkEndpointDataSource>();
|
||||
var dataSource = endpoints.ServiceProvider.GetRequiredService<FrameworkEndpointDataSource>();
|
||||
|
||||
var configurationBuilder = new FrameworkConfigurationBuilder(dataSource);
|
||||
configure(configurationBuilder);
|
||||
|
||||
routes.DataSources.Add(dataSource);
|
||||
endpoints.DataSources.Add(dataSource);
|
||||
|
||||
return dataSource;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,18 +13,18 @@ namespace Microsoft.AspNetCore.Builder
|
|||
{
|
||||
public static class EndpointRouteBuilderExtensions
|
||||
{
|
||||
public static IEndpointConventionBuilder MapHello(this IEndpointRouteBuilder routes, string pattern, string greeter)
|
||||
public static IEndpointConventionBuilder MapHello(this IEndpointRouteBuilder endpoints, string pattern, string greeter)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
var pipeline = routes.CreateApplicationBuilder()
|
||||
var pipeline = endpoints.CreateApplicationBuilder()
|
||||
.UseHello(greeter)
|
||||
.Build();
|
||||
|
||||
return routes.Map(pattern, pipeline);
|
||||
return endpoints.Map(pattern, pipeline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,11 +32,13 @@ namespace RoutingSandbox
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRouting(builder =>
|
||||
app.UseStaticFiles();
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
builder.MapHello("/helloworld", "World");
|
||||
endpoints.MapHello("/helloworld", "World");
|
||||
|
||||
builder.MapGet(
|
||||
endpoints.MapGet(
|
||||
"/",
|
||||
(httpContext) =>
|
||||
{
|
||||
|
|
@ -58,7 +60,7 @@ namespace RoutingSandbox
|
|||
response.ContentType = "text/plain";
|
||||
return response.WriteAsync(sb.ToString());
|
||||
});
|
||||
builder.MapGet(
|
||||
endpoints.MapGet(
|
||||
"/plaintext",
|
||||
(httpContext) =>
|
||||
{
|
||||
|
|
@ -69,7 +71,7 @@ namespace RoutingSandbox
|
|||
response.ContentLength = payloadLength;
|
||||
return response.Body.WriteAsync(_plainTextPayload, 0, payloadLength);
|
||||
});
|
||||
builder.MapGet(
|
||||
endpoints.MapGet(
|
||||
"/graph",
|
||||
(httpContext) =>
|
||||
{
|
||||
|
|
@ -83,11 +85,11 @@ namespace RoutingSandbox
|
|||
return Task.CompletedTask;
|
||||
}).WithDisplayName("DFA Graph");
|
||||
|
||||
builder.MapGet("/attributes", HandlerWithAttributes);
|
||||
endpoints.MapGet("/attributes", HandlerWithAttributes);
|
||||
|
||||
builder.Map("/getwithattributes", Handler);
|
||||
endpoints.Map("/getwithattributes", Handler);
|
||||
|
||||
builder.MapFramework(frameworkBuilder =>
|
||||
endpoints.MapFramework(frameworkBuilder =>
|
||||
{
|
||||
frameworkBuilder.AddPattern("/transform/{hub:slugify=TestHub}/{method:slugify=TestMethod}");
|
||||
frameworkBuilder.AddPattern("/{hub}/{method=TestMethod}");
|
||||
|
|
@ -98,7 +100,6 @@ namespace RoutingSandbox
|
|||
});
|
||||
});
|
||||
|
||||
app.UseStaticFiles();
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
|
|
|
|||
|
|
@ -13,18 +13,18 @@ namespace Microsoft.AspNetCore.Builder
|
|||
{
|
||||
public static class EndpointRouteBuilderExtensions
|
||||
{
|
||||
public static IEndpointConventionBuilder MapHello(this IEndpointRouteBuilder routes, string template, string greeter)
|
||||
public static IEndpointConventionBuilder MapHello(this IEndpointRouteBuilder endpoints, string template, string greeter)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
var pipeline = routes.CreateApplicationBuilder()
|
||||
var pipeline = endpoints.CreateApplicationBuilder()
|
||||
.UseHello(greeter)
|
||||
.Build();
|
||||
|
||||
return routes.Map(template, pipeline).WithDisplayName("Hello " + greeter);
|
||||
return endpoints.Map(template, pipeline).WithDisplayName("Hello " + greeter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,22 +16,21 @@ namespace RoutingWebSite
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapFallback("/prefix/{*path:nonfile}", (context) =>
|
||||
endpoints.MapFallback("/prefix/{*path:nonfile}", (context) =>
|
||||
{
|
||||
return context.Response.WriteAsync("FallbackCustomPattern");
|
||||
});
|
||||
|
||||
routes.MapFallback((context) =>
|
||||
endpoints.MapFallback((context) =>
|
||||
{
|
||||
return context.Response.WriteAsync("FallbackDefaultPattern");
|
||||
});
|
||||
|
||||
routes.MapHello("/helloworld", "World");
|
||||
endpoints.MapHello("/helloworld", "World");
|
||||
});
|
||||
|
||||
app.UseEndpoint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,11 +36,20 @@ namespace RoutingWebSite
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
{
|
||||
routes.MapHello("/helloworld", "World");
|
||||
app.UseStaticFiles();
|
||||
|
||||
routes.MapGet(
|
||||
app.UseRouting();
|
||||
|
||||
app.Map("/Branch1", branch => SetupBranch(branch, "Branch1"));
|
||||
app.Map("/Branch2", branch => SetupBranch(branch, "Branch2"));
|
||||
|
||||
// Imagine some more stuff here...
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapHello("/helloworld", "World");
|
||||
|
||||
endpoints.MapGet(
|
||||
"/",
|
||||
(httpContext) =>
|
||||
{
|
||||
|
|
@ -58,7 +67,7 @@ namespace RoutingWebSite
|
|||
response.ContentType = "text/plain";
|
||||
return response.WriteAsync(sb.ToString());
|
||||
});
|
||||
routes.MapGet(
|
||||
endpoints.MapGet(
|
||||
"/plaintext",
|
||||
(httpContext) =>
|
||||
{
|
||||
|
|
@ -69,7 +78,7 @@ namespace RoutingWebSite
|
|||
response.ContentLength = payloadLength;
|
||||
return response.Body.WriteAsync(_plainTextPayload, 0, payloadLength);
|
||||
});
|
||||
routes.MapGet(
|
||||
endpoints.MapGet(
|
||||
"/convention",
|
||||
(httpContext) =>
|
||||
{
|
||||
|
|
@ -79,7 +88,7 @@ namespace RoutingWebSite
|
|||
{
|
||||
b.Metadata.Add(new CustomMetadata());
|
||||
});
|
||||
routes.MapGet(
|
||||
endpoints.MapGet(
|
||||
"/withconstraints/{id:endsWith(_001)}",
|
||||
(httpContext) =>
|
||||
{
|
||||
|
|
@ -88,7 +97,7 @@ namespace RoutingWebSite
|
|||
response.ContentType = "text/plain";
|
||||
return response.WriteAsync("WithConstraints");
|
||||
});
|
||||
routes.MapGet(
|
||||
endpoints.MapGet(
|
||||
"/withoptionalconstraints/{id:endsWith(_001)?}",
|
||||
(httpContext) =>
|
||||
{
|
||||
|
|
@ -97,7 +106,7 @@ namespace RoutingWebSite
|
|||
response.ContentType = "text/plain";
|
||||
return response.WriteAsync("withoptionalconstraints");
|
||||
});
|
||||
routes.MapGet(
|
||||
endpoints.MapGet(
|
||||
"/WithSingleAsteriskCatchAll/{*path}",
|
||||
(httpContext) =>
|
||||
{
|
||||
|
|
@ -109,7 +118,7 @@ namespace RoutingWebSite
|
|||
return response.WriteAsync(
|
||||
"Link: " + linkGenerator.GetPathByRouteValues(httpContext, "WithSingleAsteriskCatchAll", new { }));
|
||||
}).WithMetadata(new RouteNameMetadata(routeName: "WithSingleAsteriskCatchAll"));
|
||||
routes.MapGet(
|
||||
endpoints.MapGet(
|
||||
"/WithDoubleAsteriskCatchAll/{**path}",
|
||||
(httpContext) =>
|
||||
{
|
||||
|
|
@ -122,34 +131,25 @@ namespace RoutingWebSite
|
|||
"Link: " + linkGenerator.GetPathByRouteValues(httpContext, "WithDoubleAsteriskCatchAll", new { }));
|
||||
}).WithMetadata(new RouteNameMetadata(routeName: "WithDoubleAsteriskCatchAll"));
|
||||
|
||||
MapHostEndpoint(routes);
|
||||
MapHostEndpoint(routes, "*.0.0.1");
|
||||
MapHostEndpoint(routes, "127.0.0.1");
|
||||
MapHostEndpoint(routes, "*.0.0.1:5000", "*.0.0.1:5001");
|
||||
MapHostEndpoint(routes, "contoso.com:*", "*.contoso.com:*");
|
||||
MapHostEndpoint(endpoints);
|
||||
MapHostEndpoint(endpoints, "*.0.0.1");
|
||||
MapHostEndpoint(endpoints, "127.0.0.1");
|
||||
MapHostEndpoint(endpoints, "*.0.0.1:5000", "*.0.0.1:5001");
|
||||
MapHostEndpoint(endpoints, "contoso.com:*", "*.contoso.com:*");
|
||||
});
|
||||
|
||||
app.Map("/Branch1", branch => SetupBranch(branch, "Branch1"));
|
||||
app.Map("/Branch2", branch => SetupBranch(branch, "Branch2"));
|
||||
|
||||
app.UseStaticFiles();
|
||||
|
||||
// Imagine some more stuff here...
|
||||
|
||||
app.UseEndpoint();
|
||||
}
|
||||
|
||||
private class CustomMetadata
|
||||
{
|
||||
}
|
||||
|
||||
private IEndpointConventionBuilder MapHostEndpoint(IEndpointRouteBuilder routes, params string[] hosts)
|
||||
private IEndpointConventionBuilder MapHostEndpoint(IEndpointRouteBuilder endpoints, params string[] hosts)
|
||||
{
|
||||
var hostsDisplay = (hosts == null || hosts.Length == 0)
|
||||
? "*:*"
|
||||
: string.Join(",", hosts.Select(h => h.Contains(':') ? h : h + ":*"));
|
||||
|
||||
var conventionBuilder = routes.MapGet(
|
||||
var conventionBuilder = endpoints.MapGet(
|
||||
"api/DomainWildcard",
|
||||
httpContext =>
|
||||
{
|
||||
|
|
@ -170,12 +170,11 @@ namespace RoutingWebSite
|
|||
|
||||
private void SetupBranch(IApplicationBuilder app, string name)
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapGet("api/get/{id}", (context) => context.Response.WriteAsync($"{name} - API Get {context.GetRouteData().Values["id"]}"));
|
||||
endpoints.MapGet("api/get/{id}", (context) => context.Response.WriteAsync($"{name} - API Get {context.GetRouteData().Values["id"]}"));
|
||||
});
|
||||
|
||||
app.UseEndpoint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,15 @@ namespace ApiAuthSample
|
|||
app.UseStaticFiles();
|
||||
app.UseIdentityServer();
|
||||
|
||||
app.UseMvc();
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,13 +58,15 @@ namespace IdentitySample.DefaultUI
|
|||
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseRouting();
|
||||
|
||||
app.UseMvc(routes =>
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
name: "default",
|
||||
template: "{controller=Home}/{action=Index}/{id?}");
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
endpoints.MapRazorPages();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,13 +70,15 @@ namespace IdentitySample
|
|||
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseRouting();
|
||||
|
||||
app.UseMvc(routes =>
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
name: "default",
|
||||
template: "{controller=Home}/{action=Index}/{id?}");
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
endpoints.MapRazorPages();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,9 +57,15 @@ namespace Identity.DefaultUI.WebSite
|
|||
app.UseStaticFiles();
|
||||
app.UseCookiePolicy();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseRouting();
|
||||
|
||||
app.UseMvc();
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,9 +77,23 @@ namespace Identity.DefaultUI.WebSite
|
|||
app.UseStaticFiles();
|
||||
app.UseCookiePolicy();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthentication();
|
||||
|
||||
app.UseMvc();
|
||||
// This has to be disabled due to https://github.com/aspnet/AspNetCore/issues/8387
|
||||
//
|
||||
// UseAuthorization does not currently work with Razor pages, and it impacts
|
||||
// many of the tests here. Uncomment when this is fixed so that we test what is recommended
|
||||
// for users.
|
||||
//
|
||||
//app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
endpoints.MapRazorPages();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,18 +57,18 @@ namespace SampleDestination
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRouting(routing =>
|
||||
{
|
||||
routing.Map("/allow-origin", HandleRequest).WithCorsPolicy("AllowOrigin");
|
||||
routing.Map("/allow-header-method", HandleRequest).WithCorsPolicy("AllowHeaderMethod");
|
||||
routing.Map("/allow-credentials", HandleRequest).WithCorsPolicy("AllowCredentials");
|
||||
routing.Map("/exposed-header", HandleRequest).WithCorsPolicy("ExposedHeader");
|
||||
routing.Map("/allow-all", HandleRequest).WithCorsPolicy("AllowAll");
|
||||
});
|
||||
app.UseRouting();
|
||||
|
||||
app.UseCors();
|
||||
|
||||
app.UseEndpoint();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.Map("/allow-origin", HandleRequest).WithCorsPolicy("AllowOrigin");
|
||||
endpoints.Map("/allow-header-method", HandleRequest).WithCorsPolicy("AllowHeaderMethod");
|
||||
endpoints.Map("/allow-credentials", HandleRequest).WithCorsPolicy("AllowCredentials");
|
||||
endpoints.Map("/exposed-header", HandleRequest).WithCorsPolicy("ExposedHeader");
|
||||
endpoints.Map("/allow-all", HandleRequest).WithCorsPolicy("AllowAll");
|
||||
});
|
||||
|
||||
app.Run(async (context) =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ namespace Microsoft.AspNetCore.Builder
|
|||
}
|
||||
public static partial class HealthCheckEndpointRouteBuilderExtensions
|
||||
{
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapHealthChecks(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapHealthChecks(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions options) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapHealthChecks(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string pattern) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapHealthChecks(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string pattern, Microsoft.AspNetCore.Diagnostics.HealthChecks.HealthCheckOptions options) { throw null; }
|
||||
}
|
||||
}
|
||||
namespace Microsoft.AspNetCore.Diagnostics.HealthChecks
|
||||
|
|
|
|||
|
|
@ -20,36 +20,36 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// <summary>
|
||||
/// Adds a health checks endpoint to the <see cref="IEndpointRouteBuilder"/> with the specified template.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the health checks endpoint to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the health checks endpoint to.</param>
|
||||
/// <param name="pattern">The URL pattern of the health checks endpoint.</param>
|
||||
/// <returns>A convention routes for the health checks endpoint.</returns>
|
||||
public static IEndpointConventionBuilder MapHealthChecks(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string pattern)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
return MapHealthChecksCore(routes, pattern, null);
|
||||
return MapHealthChecksCore(endpoints, pattern, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a health checks endpoint to the <see cref="IEndpointRouteBuilder"/> with the specified template and options.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the health checks endpoint to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the health checks endpoint to.</param>
|
||||
/// <param name="pattern">The URL pattern of the health checks endpoint.</param>
|
||||
/// <param name="options">A <see cref="HealthCheckOptions"/> used to configure the health checks.</param>
|
||||
/// <returns>A convention routes for the health checks endpoint.</returns>
|
||||
public static IEndpointConventionBuilder MapHealthChecks(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string pattern,
|
||||
HealthCheckOptions options)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (options == null)
|
||||
|
|
@ -57,12 +57,12 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
return MapHealthChecksCore(routes, pattern, options);
|
||||
return MapHealthChecksCore(endpoints, pattern, options);
|
||||
}
|
||||
|
||||
private static IEndpointConventionBuilder MapHealthChecksCore(IEndpointRouteBuilder routes, string pattern, HealthCheckOptions options)
|
||||
private static IEndpointConventionBuilder MapHealthChecksCore(IEndpointRouteBuilder endpoints, string pattern, HealthCheckOptions options)
|
||||
{
|
||||
if (routes.ServiceProvider.GetService(typeof(HealthCheckService)) == null)
|
||||
if (endpoints.ServiceProvider.GetService(typeof(HealthCheckService)) == null)
|
||||
{
|
||||
throw new InvalidOperationException(Resources.FormatUnableToFindServices(
|
||||
nameof(IServiceCollection),
|
||||
|
|
@ -72,11 +72,11 @@ namespace Microsoft.AspNetCore.Builder
|
|||
|
||||
var args = options != null ? new[] { Options.Create(options) } : Array.Empty<object>();
|
||||
|
||||
var pipeline = routes.CreateApplicationBuilder()
|
||||
var pipeline = endpoints.CreateApplicationBuilder()
|
||||
.UseMiddleware<HealthCheckMiddleware>(args)
|
||||
.Build();
|
||||
|
||||
return routes.Map(pattern, pipeline).WithDisplayName(DefaultDisplayName);
|
||||
return endpoints.Map(pattern, pipeline).WithDisplayName(DefaultDisplayName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,9 +24,10 @@ namespace Microsoft.AspNetCore.Diagnostics.HealthChecks
|
|||
var builder = new WebHostBuilder()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapHealthChecks("/healthz");
|
||||
endpoints.MapHealthChecks("/healthz");
|
||||
});
|
||||
})
|
||||
.ConfigureServices(services =>
|
||||
|
|
@ -50,9 +51,10 @@ namespace Microsoft.AspNetCore.Diagnostics.HealthChecks
|
|||
var builder = new WebHostBuilder()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapHealthChecks("/healthz");
|
||||
endpoints.MapHealthChecks("/healthz");
|
||||
});
|
||||
})
|
||||
.ConfigureServices(services =>
|
||||
|
|
@ -79,9 +81,10 @@ namespace Microsoft.AspNetCore.Diagnostics.HealthChecks
|
|||
var builder = new WebHostBuilder()
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapHealthChecks("/healthz", new HealthCheckOptions
|
||||
endpoints.MapHealthChecks("/healthz", new HealthCheckOptions
|
||||
{
|
||||
ResponseWriter = async (context, report) =>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -42,11 +42,11 @@ namespace NodeServicesExamples
|
|||
});
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.UseMvc(routes =>
|
||||
app.UseRouting();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
name: "default",
|
||||
template: "{controller=Home}/{action=Index}/{id?}");
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -649,6 +649,9 @@ For the list of available options, please see [Webpack Hot Middleware docs](http
|
|||
|
||||
## Routing helper: MapSpaFallbackRoute
|
||||
|
||||
*Note: this functionality has been superseded by `endpoints.MapFallbackToFile(...)` provided by endpoint routing.
|
||||
`MapFallbackToFile` behaves similarly to `MapSpaFallbackRoute`.*
|
||||
|
||||
In most single-page applications, you'll want client-side routing as well as your server-side routing. Most of the time, the two routing systems work independently without interfering. However, there is one case where things get challenging: identifying 404s.
|
||||
|
||||
If a request arrives for `/some/page`, and it doesn't match any server-side route, it's likely that you want to return HTML that starts up your client-side application, which probably understands the route `/some/page`. But if a request arrives for `/images/user-512.png`, and it doesn't match any server-side route or static file, it's **not** likely that your client-side application would handle it - you probably want to return a 404.
|
||||
|
|
|
|||
|
|
@ -32,11 +32,10 @@ namespace Webpack
|
|||
});
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.UseMvc(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
name: "default",
|
||||
template: "{controller=Home}/{action=Index}/{id?}");
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,10 +61,10 @@ namespace Microsoft.AspNetCore.Builder
|
|||
}
|
||||
public static partial class StaticFilesEndpointRouteBuilderExtensions
|
||||
{
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapFallbackToFile(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string filePath) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapFallbackToFile(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string filePath, Microsoft.AspNetCore.Builder.StaticFileOptions options) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapFallbackToFile(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, string filePath) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapFallbackToFile(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, string filePath, Microsoft.AspNetCore.Builder.StaticFileOptions options) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapFallbackToFile(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string filePath) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapFallbackToFile(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string filePath, Microsoft.AspNetCore.Builder.StaticFileOptions options) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapFallbackToFile(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string pattern, string filePath) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapFallbackToFile(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string pattern, string filePath, Microsoft.AspNetCore.Builder.StaticFileOptions options) { throw null; }
|
||||
}
|
||||
}
|
||||
namespace Microsoft.AspNetCore.StaticFiles
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// requests for non-filenames with the lowest possible priority. The request will be routed to a
|
||||
/// <see cref="StaticFileMiddleware"/> that attempts to serve the file specified by <paramref name="filePath"/>.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/>.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/>.</param>
|
||||
/// <param name="filePath">The file path of the file to serve.</param>
|
||||
/// <returns>The <see cref="IEndpointRouteBuilder"/></returns>
|
||||
/// <remarks>
|
||||
|
|
@ -38,12 +38,12 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </para>
|
||||
/// </remarks>
|
||||
public static IEndpointConventionBuilder MapFallbackToFile(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string filePath)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (filePath == null)
|
||||
|
|
@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(filePath));
|
||||
}
|
||||
|
||||
return routes.MapFallback(CreateRequestDelegate(routes, filePath));
|
||||
return endpoints.MapFallback(CreateRequestDelegate(endpoints, filePath));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -59,7 +59,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// requests for non-filenames with the lowest possible priority. The request will be routed to a
|
||||
/// <see cref="StaticFileMiddleware"/> that attempts to serve the file specified by <paramref name="filePath"/>.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/>.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/>.</param>
|
||||
/// <param name="filePath">The file path of the file to serve.</param>
|
||||
/// <param name="options"><see cref="StaticFileOptions"/> for the <see cref="StaticFileMiddleware"/>.</param>
|
||||
/// <returns>The <see cref="IEndpointRouteBuilder"/></returns>
|
||||
|
|
@ -76,13 +76,13 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </para>
|
||||
/// </remarks>
|
||||
public static IEndpointConventionBuilder MapFallbackToFile(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string filePath,
|
||||
StaticFileOptions options)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (filePath == null)
|
||||
|
|
@ -90,7 +90,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(filePath));
|
||||
}
|
||||
|
||||
return routes.MapFallback(CreateRequestDelegate(routes, filePath, options));
|
||||
return endpoints.MapFallback(CreateRequestDelegate(endpoints, filePath, options));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -98,7 +98,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// requests for non-filenames with the lowest possible priority. The request will be routed to a
|
||||
/// <see cref="StaticFileMiddleware"/> that attempts to serve the file specified by <paramref name="filePath"/>.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/>.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/>.</param>
|
||||
/// <param name="pattern">The route pattern.</param>
|
||||
/// <param name="filePath">The file path of the file to serve.</param>
|
||||
/// <returns>The <see cref="IEndpointRouteBuilder"/></returns>
|
||||
|
|
@ -121,13 +121,13 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </para>
|
||||
/// </remarks>
|
||||
public static IEndpointConventionBuilder MapFallbackToFile(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string pattern,
|
||||
string filePath)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (pattern == null)
|
||||
|
|
@ -140,7 +140,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(filePath));
|
||||
}
|
||||
|
||||
return routes.MapFallback(pattern, CreateRequestDelegate(routes, filePath));
|
||||
return endpoints.MapFallback(pattern, CreateRequestDelegate(endpoints, filePath));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -148,7 +148,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// requests for non-filenames with the lowest possible priority. The request will be routed to a
|
||||
/// <see cref="StaticFileMiddleware"/> that attempts to serve the file specified by <paramref name="filePath"/>.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/>.</param>\
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/>.</param>\
|
||||
/// <param name="pattern">The route pattern.</param>
|
||||
/// <param name="filePath">The file path of the file to serve.</param>
|
||||
/// <param name="options"><see cref="StaticFileOptions"/> for the <see cref="StaticFileMiddleware"/>.</param>
|
||||
|
|
@ -169,14 +169,14 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </para>
|
||||
/// </remarks>
|
||||
public static IEndpointConventionBuilder MapFallbackToFile(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string pattern,
|
||||
string filePath,
|
||||
StaticFileOptions options)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (pattern == null)
|
||||
|
|
@ -189,15 +189,15 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(filePath));
|
||||
}
|
||||
|
||||
return routes.MapFallback(pattern, CreateRequestDelegate(routes, filePath, options));
|
||||
return endpoints.MapFallback(pattern, CreateRequestDelegate(endpoints, filePath, options));
|
||||
}
|
||||
|
||||
private static RequestDelegate CreateRequestDelegate(
|
||||
IEndpointRouteBuilder routes,
|
||||
IEndpointRouteBuilder endpoints,
|
||||
string filePath,
|
||||
StaticFileOptions options = null)
|
||||
{
|
||||
var app = routes.CreateApplicationBuilder();
|
||||
var app = endpoints.CreateApplicationBuilder();
|
||||
app.Use(next => context =>
|
||||
{
|
||||
context.Request.Path = "/" + filePath;
|
||||
|
|
|
|||
|
|
@ -35,15 +35,15 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
.Configure(app =>
|
||||
{
|
||||
var environment = app.ApplicationServices.GetRequiredService<IWebHostEnvironment>();
|
||||
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.Map("/hello", context =>
|
||||
endpoints.Map("/hello", context =>
|
||||
{
|
||||
return context.Response.WriteAsync("Hello, world!");
|
||||
});
|
||||
|
||||
routes.MapFallbackToFile("default.html", new StaticFileOptions()
|
||||
endpoints.MapFallbackToFile("default.html", new StaticFileOptions()
|
||||
{
|
||||
FileProvider = new PhysicalFileProvider(Path.Combine(environment.WebRootPath, "SubFolder")),
|
||||
});
|
||||
|
|
@ -83,14 +83,15 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
.UseWebRoot(AppContext.BaseDirectory)
|
||||
.Configure(app =>
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.Map("/hello", context =>
|
||||
endpoints.Map("/hello", context =>
|
||||
{
|
||||
return context.Response.WriteAsync("Hello, world!");
|
||||
});
|
||||
|
||||
routes.MapFallbackToFile("/prefix/{*path:nonfile}", "TestDocument.txt");
|
||||
endpoints.MapFallbackToFile("/prefix/{*path:nonfile}", "TestDocument.txt");
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -50,12 +50,14 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
public async Task Endpoint_PassesThrough()
|
||||
{
|
||||
var builder = new WebHostBuilder()
|
||||
.ConfigureServices(services => services.AddSingleton(LoggerFactory))
|
||||
.ConfigureServices(services => { services.AddSingleton(LoggerFactory); services.AddRouting(); })
|
||||
.UseKestrel()
|
||||
.UseWebRoot(AppContext.BaseDirectory)
|
||||
.Configure(app =>
|
||||
{
|
||||
// Routing first => static files noops
|
||||
app.UseRouting();
|
||||
|
||||
app.Use(next => context =>
|
||||
{
|
||||
// Assign an endpoint, this will make the default files noop.
|
||||
|
|
@ -70,6 +72,8 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
});
|
||||
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseEndpoints(endpoints => {});
|
||||
});
|
||||
|
||||
using (var server = builder.Start(TestUrlHelper.GetTestUrl(ServerType.Kestrel)))
|
||||
|
|
|
|||
|
|
@ -82,6 +82,8 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
var server = StaticFilesTestServer.Create(
|
||||
app =>
|
||||
{
|
||||
app.UseRouting();
|
||||
|
||||
app.Use(next => context =>
|
||||
{
|
||||
// Assign an endpoint, this will make the default files noop.
|
||||
|
|
@ -100,8 +102,10 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
RequestPath = new PathString(""),
|
||||
FileProvider = fileProvider
|
||||
});
|
||||
|
||||
app.UseEndpoints(endpoints => {});
|
||||
},
|
||||
services => services.AddDirectoryBrowser());
|
||||
services => { services.AddDirectoryBrowser(); services.AddRouting(); });
|
||||
|
||||
var response = await server.CreateRequest("/SubFolder/").GetAsync();
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
|
|
|||
|
|
@ -96,6 +96,8 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
var server = StaticFilesTestServer.Create(
|
||||
app =>
|
||||
{
|
||||
app.UseRouting();
|
||||
|
||||
app.Use(next => context =>
|
||||
{
|
||||
// Assign an endpoint, this will make the directory browser noop
|
||||
|
|
@ -115,8 +117,10 @@ namespace Microsoft.AspNetCore.StaticFiles
|
|||
RequestPath = new PathString(""),
|
||||
FileProvider = fileProvider
|
||||
});
|
||||
|
||||
app.UseEndpoints(endpoints => {});
|
||||
},
|
||||
services => services.AddDirectoryBrowser());
|
||||
services => { services.AddDirectoryBrowser(); services.AddRouting(); });
|
||||
|
||||
var response = await server.CreateRequest("/").GetAsync();
|
||||
Assert.Equal(HttpStatusCode.NotAcceptable, response.StatusCode);
|
||||
|
|
|
|||
|
|
@ -141,25 +141,31 @@ namespace MusicStore
|
|||
// Add static files to the request pipeline
|
||||
app.UseStaticFiles();
|
||||
|
||||
// Add authentication to the request pipeline
|
||||
// Add the endpoint routing matcher middleware to the request pipeline
|
||||
app.UseRouting();
|
||||
|
||||
// Add cookie-based authentication to the request pipeline
|
||||
app.UseAuthentication();
|
||||
|
||||
// Add MVC to the request pipeline
|
||||
app.UseMvc(routes =>
|
||||
// Add the authorization middleware to the request pipeline
|
||||
app.UseAuthorization();
|
||||
|
||||
// Add endpoints to the request pipeline
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "areaRoute",
|
||||
template: "{area:exists}/{controller}/{action}",
|
||||
pattern: "{area:exists}/{controller}/{action}",
|
||||
defaults: new { action = "Index" });
|
||||
|
||||
routes.MapRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "default",
|
||||
template: "{controller}/{action}/{id?}",
|
||||
pattern: "{controller}/{action}/{id?}",
|
||||
defaults: new { controller = "Home", action = "Index" });
|
||||
|
||||
routes.MapRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "api",
|
||||
template: "{controller}/{id?}");
|
||||
pattern: "{controller}/{id?}");
|
||||
});
|
||||
|
||||
//Populates the MusicStore sample data
|
||||
|
|
|
|||
|
|
@ -181,25 +181,31 @@ namespace MusicStore
|
|||
// Add static files to the request pipeline
|
||||
app.UseStaticFiles();
|
||||
|
||||
// Add the endpoint routing matcher middleware to the request pipeline
|
||||
app.UseRouting();
|
||||
|
||||
// Add cookie-based authentication to the request pipeline
|
||||
app.UseAuthentication();
|
||||
|
||||
// Add MVC to the request pipeline
|
||||
app.UseMvc(routes =>
|
||||
// Add the authorization middleware to the request pipeline
|
||||
app.UseAuthorization();
|
||||
|
||||
// Add endpoints to the request pipeline
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "areaRoute",
|
||||
template: "{area:exists}/{controller}/{action}",
|
||||
pattern: "{area:exists}/{controller}/{action}",
|
||||
defaults: new { action = "Index" });
|
||||
|
||||
routes.MapRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "default",
|
||||
template: "{controller}/{action}/{id?}",
|
||||
pattern: "{controller}/{action}/{id?}",
|
||||
defaults: new { controller = "Home", action = "Index" });
|
||||
|
||||
routes.MapRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "api",
|
||||
template: "{controller}/{id?}");
|
||||
pattern: "{controller}/{id?}");
|
||||
});
|
||||
|
||||
//Populates the MusicStore sample data
|
||||
|
|
|
|||
|
|
@ -195,25 +195,31 @@ namespace MusicStore
|
|||
// Add static files to the request pipeline
|
||||
app.UseStaticFiles();
|
||||
|
||||
// Add the endpoint routing matcher middleware to the request pipeline
|
||||
app.UseRouting();
|
||||
|
||||
// Add cookie-based authentication to the request pipeline
|
||||
app.UseAuthentication();
|
||||
|
||||
// Add MVC to the request pipeline
|
||||
app.UseMvc(routes =>
|
||||
// Add the authorization middleware to the request pipeline
|
||||
app.UseAuthorization();
|
||||
|
||||
// Add endpoints to the request pipeline
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "areaRoute",
|
||||
template: "{area:exists}/{controller}/{action}",
|
||||
pattern: "{area:exists}/{controller}/{action}",
|
||||
defaults: new { action = "Index" });
|
||||
|
||||
routes.MapRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "default",
|
||||
template: "{controller}/{action}/{id?}",
|
||||
pattern: "{controller}/{action}/{id?}",
|
||||
defaults: new { controller = "Home", action = "Index" });
|
||||
|
||||
routes.MapRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "api",
|
||||
template: "{controller}/{id?}");
|
||||
pattern: "{controller}/{id?}");
|
||||
});
|
||||
|
||||
//Populates the MusicStore sample data
|
||||
|
|
|
|||
|
|
@ -142,22 +142,31 @@ namespace MusicStore
|
|||
// Add static files to the request pipeline
|
||||
app.UseStaticFiles();
|
||||
|
||||
// Add MVC to the request pipeline
|
||||
app.UseMvc(routes =>
|
||||
// Add the endpoint routing matcher middleware to the request pipeline
|
||||
app.UseRouting();
|
||||
|
||||
// Add cookie-based authentication to the request pipeline
|
||||
app.UseAuthentication();
|
||||
|
||||
// Add the authorization middleware to the request pipeline
|
||||
app.UseAuthorization();
|
||||
|
||||
// Add endpoints to the request pipeline
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "areaRoute",
|
||||
template: "{area:exists}/{controller}/{action}",
|
||||
pattern: "{area:exists}/{controller}/{action}",
|
||||
defaults: new { action = "Index" });
|
||||
|
||||
routes.MapRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "default",
|
||||
template: "{controller}/{action}/{id?}",
|
||||
pattern: "{controller}/{action}/{id?}",
|
||||
defaults: new { controller = "Home", action = "Index" });
|
||||
|
||||
routes.MapRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "api",
|
||||
template: "{controller}/{id?}");
|
||||
pattern: "{controller}/{id?}");
|
||||
});
|
||||
|
||||
//Populates the MusicStore sample data
|
||||
|
|
|
|||
|
|
@ -140,22 +140,31 @@ namespace MusicStore
|
|||
// Add static files to the request pipeline
|
||||
app.UseStaticFiles();
|
||||
|
||||
// Add MVC to the request pipeline
|
||||
app.UseMvc(routes =>
|
||||
// Add the endpoint routing matcher middleware to the request pipeline
|
||||
app.UseRouting();
|
||||
|
||||
// Add cookie-based authentication to the request pipeline
|
||||
app.UseAuthentication();
|
||||
|
||||
// Add the authorization middleware to the request pipeline
|
||||
app.UseAuthorization();
|
||||
|
||||
// Add endpoints to the request pipeline
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "areaRoute",
|
||||
template: "{area:exists}/{controller}/{action}",
|
||||
pattern: "{area:exists}/{controller}/{action}",
|
||||
defaults: new { action = "Index" });
|
||||
|
||||
routes.MapRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "default",
|
||||
template: "{controller}/{action}/{id?}",
|
||||
pattern: "{controller}/{action}/{id?}",
|
||||
defaults: new { controller = "Home", action = "Index" });
|
||||
|
||||
routes.MapRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "api",
|
||||
template: "{controller}/{id?}");
|
||||
pattern: "{controller}/{id?}");
|
||||
});
|
||||
|
||||
//Populates the MusicStore sample data
|
||||
|
|
|
|||
|
|
@ -5,14 +5,14 @@ namespace Microsoft.AspNetCore.Builder
|
|||
{
|
||||
public static partial class ControllerEndpointRouteBuilderExtensions
|
||||
{
|
||||
public static void MapAreaControllerRoute(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string name, string areaName, string pattern, object defaults = null, object constraints = null, object dataTokens = null) { }
|
||||
public static void MapControllerRoute(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string name, string pattern, object defaults = null, object constraints = null, object dataTokens = null) { }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapControllers(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapDefaultControllerRoute(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes) { throw null; }
|
||||
public static void MapFallbackToAreaController(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string action, string controller, string area) { }
|
||||
public static void MapFallbackToAreaController(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, string action, string controller, string area) { }
|
||||
public static void MapFallbackToController(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string action, string controller) { }
|
||||
public static void MapFallbackToController(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, string action, string controller) { }
|
||||
public static void MapAreaControllerRoute(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string name, string areaName, string pattern, object defaults = null, object constraints = null, object dataTokens = null) { }
|
||||
public static void MapControllerRoute(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string name, string pattern, object defaults = null, object constraints = null, object dataTokens = null) { }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapControllers(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints) { throw null; }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapDefaultControllerRoute(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints) { throw null; }
|
||||
public static void MapFallbackToAreaController(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string action, string controller, string area) { }
|
||||
public static void MapFallbackToAreaController(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string pattern, string action, string controller, string area) { }
|
||||
public static void MapFallbackToController(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string action, string controller) { }
|
||||
public static void MapFallbackToController(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string pattern, string action, string controller) { }
|
||||
}
|
||||
public static partial class MvcApplicationBuilderExtensions
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,36 +20,36 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// <summary>
|
||||
/// Adds endpoints for controller actions to the <see cref="IEndpointRouteBuilder"/> without specifying any routes.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/>.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/>.</param>
|
||||
/// <returns>An <see cref="IEndpointConventionBuilder"/> for endpoints associated with controller actions.</returns>
|
||||
public static IEndpointConventionBuilder MapControllers(this IEndpointRouteBuilder routes)
|
||||
public static IEndpointConventionBuilder MapControllers(this IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
EnsureControllerServices(routes);
|
||||
EnsureControllerServices(endpoints);
|
||||
|
||||
return GetOrCreateDataSource(routes);
|
||||
return GetOrCreateDataSource(endpoints);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds endpoints for controller actions to the <see cref="IEndpointRouteBuilder"/> and adds the default route
|
||||
/// <c>{controller=Home}/{action=Index}/{id?}</c>.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/>.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/>.</param>
|
||||
/// <returns>An <see cref="IEndpointConventionBuilder"/> for endpoints associated with controller actions.</returns>
|
||||
public static IEndpointConventionBuilder MapDefaultControllerRoute(this IEndpointRouteBuilder routes)
|
||||
public static IEndpointConventionBuilder MapDefaultControllerRoute(this IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
EnsureControllerServices(routes);
|
||||
EnsureControllerServices(endpoints);
|
||||
|
||||
var dataSource = GetOrCreateDataSource(routes);
|
||||
var dataSource = GetOrCreateDataSource(endpoints);
|
||||
dataSource.AddRoute(new ConventionalRouteEntry(
|
||||
"default",
|
||||
"{controller=Home}/{action=Index}/{id?}",
|
||||
|
|
@ -65,7 +65,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// with the given <paramref name="name"/>, <paramref name="pattern"/>,
|
||||
/// <paramref name="defaults"/>, <paramref name="constraints"/>, and <paramref name="dataTokens"/>.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="name">The name of the route.</param>
|
||||
/// <param name="pattern">The URL pattern of the route.</param>
|
||||
/// <param name="defaults">
|
||||
|
|
@ -81,21 +81,21 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// values of the data tokens.
|
||||
/// </param>
|
||||
public static void MapControllerRoute(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string name,
|
||||
string pattern,
|
||||
object defaults = null,
|
||||
object constraints = null,
|
||||
object dataTokens = null)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
EnsureControllerServices(routes);
|
||||
EnsureControllerServices(endpoints);
|
||||
|
||||
var dataSource = GetOrCreateDataSource(routes);
|
||||
var dataSource = GetOrCreateDataSource(endpoints);
|
||||
dataSource.AddRoute(new ConventionalRouteEntry(
|
||||
name,
|
||||
pattern,
|
||||
|
|
@ -109,7 +109,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// with the given <paramref name="name"/>, <paramref name="areaName"/>, <paramref name="pattern"/>,
|
||||
/// <paramref name="defaults"/>, <paramref name="constraints"/>, and <paramref name="dataTokens"/>.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="name">The name of the route.</param>
|
||||
/// <param name="areaName">The area name.</param>
|
||||
/// <param name="pattern">The URL pattern of the route.</param>
|
||||
|
|
@ -126,7 +126,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// values of the data tokens.
|
||||
/// </param>
|
||||
public static void MapAreaControllerRoute(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string name,
|
||||
string areaName,
|
||||
string pattern,
|
||||
|
|
@ -134,9 +134,9 @@ namespace Microsoft.AspNetCore.Builder
|
|||
object constraints = null,
|
||||
object dataTokens = null)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(areaName))
|
||||
|
|
@ -150,7 +150,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
var constraintsDictionary = new RouteValueDictionary(constraints);
|
||||
constraintsDictionary["area"] = constraintsDictionary["area"] ?? new StringRouteConstraint(areaName);
|
||||
|
||||
routes.MapControllerRoute(name, pattern, defaultsDictionary, constraintsDictionary, dataTokens);
|
||||
endpoints.MapControllerRoute(name, pattern, defaultsDictionary, constraintsDictionary, dataTokens);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -158,7 +158,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// requests for non-file-names with the lowest possible priority. The request will be routed to a controller endpoint that
|
||||
/// matches <paramref name="action"/>, and <paramref name="controller"/>.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="action">The action name.</param>
|
||||
/// <param name="controller">The controller name.</param>
|
||||
/// <remarks>
|
||||
|
|
@ -184,13 +184,13 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </para>
|
||||
/// </remarks>
|
||||
public static void MapFallbackToController(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string action,
|
||||
string controller)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (action == null)
|
||||
|
|
@ -203,14 +203,14 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(controller));
|
||||
}
|
||||
|
||||
EnsureControllerServices(routes);
|
||||
EnsureControllerServices(endpoints);
|
||||
|
||||
// Called for side-effect to make sure that the data source is registered.
|
||||
GetOrCreateDataSource(routes);
|
||||
GetOrCreateDataSource(endpoints);
|
||||
|
||||
// Maps a fallback endpoint with an empty delegate. This is OK because
|
||||
// we don't expect the delegate to run.
|
||||
routes.MapFallback(context => Task.CompletedTask).Add(b =>
|
||||
endpoints.MapFallback(context => Task.CompletedTask).Add(b =>
|
||||
{
|
||||
// MVC registers a policy that looks for this metadata.
|
||||
b.Metadata.Add(CreateDynamicControllerMetadata(action, controller, area: null));
|
||||
|
|
@ -222,7 +222,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// requests for non-file-names with the lowest possible priority. The request will be routed to a controller endpoint that
|
||||
/// matches <paramref name="action"/>, and <paramref name="controller"/>.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="pattern">The route pattern.</param>
|
||||
/// <param name="action">The action name.</param>
|
||||
/// <param name="controller">The controller name.</param>
|
||||
|
|
@ -252,14 +252,14 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </para>
|
||||
/// </remarks>
|
||||
public static void MapFallbackToController(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string pattern,
|
||||
string action,
|
||||
string controller)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (pattern == null)
|
||||
|
|
@ -277,14 +277,14 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(controller));
|
||||
}
|
||||
|
||||
EnsureControllerServices(routes);
|
||||
EnsureControllerServices(endpoints);
|
||||
|
||||
// Called for side-effect to make sure that the data source is registered.
|
||||
GetOrCreateDataSource(routes);
|
||||
GetOrCreateDataSource(endpoints);
|
||||
|
||||
// Maps a fallback endpoint with an empty delegate. This is OK because
|
||||
// we don't expect the delegate to run.
|
||||
routes.MapFallback(pattern, context => Task.CompletedTask).Add(b =>
|
||||
endpoints.MapFallback(pattern, context => Task.CompletedTask).Add(b =>
|
||||
{
|
||||
// MVC registers a policy that looks for this metadata.
|
||||
b.Metadata.Add(CreateDynamicControllerMetadata(action, controller, area: null));
|
||||
|
|
@ -296,7 +296,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// requests for non-file-names with the lowest possible priority. The request will be routed to a controller endpoint that
|
||||
/// matches <paramref name="action"/>, <paramref name="controller"/>, and <paramref name="area"/>.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="action">The action name.</param>
|
||||
/// <param name="controller">The controller name.</param>
|
||||
/// <param name="area">The area name.</param>
|
||||
|
|
@ -323,14 +323,14 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </para>
|
||||
/// </remarks>
|
||||
public static void MapFallbackToAreaController(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string action,
|
||||
string controller,
|
||||
string area)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (action == null)
|
||||
|
|
@ -343,14 +343,14 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(controller));
|
||||
}
|
||||
|
||||
EnsureControllerServices(routes);
|
||||
EnsureControllerServices(endpoints);
|
||||
|
||||
// Called for side-effect to make sure that the data source is registered.
|
||||
GetOrCreateDataSource(routes);
|
||||
GetOrCreateDataSource(endpoints);
|
||||
|
||||
// Maps a fallback endpoint with an empty delegate. This is OK because
|
||||
// we don't expect the delegate to run.
|
||||
routes.MapFallback(context => Task.CompletedTask).Add(b =>
|
||||
endpoints.MapFallback(context => Task.CompletedTask).Add(b =>
|
||||
{
|
||||
// MVC registers a policy that looks for this metadata.
|
||||
b.Metadata.Add(CreateDynamicControllerMetadata(action, controller, area));
|
||||
|
|
@ -362,7 +362,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// requests for non-file-names with the lowest possible priority. The request will be routed to a controller endpoint that
|
||||
/// matches <paramref name="action"/>, <paramref name="controller"/>, and <paramref name="area"/>.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="pattern">The route pattern.</param>
|
||||
/// <param name="action">The action name.</param>
|
||||
/// <param name="controller">The controller name.</param>
|
||||
|
|
@ -393,15 +393,15 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </para>
|
||||
/// </remarks>
|
||||
public static void MapFallbackToAreaController(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string pattern,
|
||||
string action,
|
||||
string controller,
|
||||
string area)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (pattern == null)
|
||||
|
|
@ -419,14 +419,14 @@ namespace Microsoft.AspNetCore.Builder
|
|||
throw new ArgumentNullException(nameof(controller));
|
||||
}
|
||||
|
||||
EnsureControllerServices(routes);
|
||||
EnsureControllerServices(endpoints);
|
||||
|
||||
// Called for side-effect to make sure that the data source is registered.
|
||||
GetOrCreateDataSource(routes);
|
||||
GetOrCreateDataSource(endpoints);
|
||||
|
||||
// Maps a fallback endpoint with an empty delegate. This is OK because
|
||||
// we don't expect the delegate to run.
|
||||
routes.MapFallback(pattern, context => Task.CompletedTask).Add(b =>
|
||||
endpoints.MapFallback(pattern, context => Task.CompletedTask).Add(b =>
|
||||
{
|
||||
// MVC registers a policy that looks for this metadata.
|
||||
b.Metadata.Add(CreateDynamicControllerMetadata(action, controller, area));
|
||||
|
|
@ -443,9 +443,9 @@ namespace Microsoft.AspNetCore.Builder
|
|||
});
|
||||
}
|
||||
|
||||
private static void EnsureControllerServices(IEndpointRouteBuilder routes)
|
||||
private static void EnsureControllerServices(IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
var marker = routes.ServiceProvider.GetService<MvcMarkerService>();
|
||||
var marker = endpoints.ServiceProvider.GetService<MvcMarkerService>();
|
||||
if (marker == null)
|
||||
{
|
||||
throw new InvalidOperationException(Resources.FormatUnableToFindServices(
|
||||
|
|
@ -455,13 +455,13 @@ namespace Microsoft.AspNetCore.Builder
|
|||
}
|
||||
}
|
||||
|
||||
private static ControllerActionEndpointDataSource GetOrCreateDataSource(IEndpointRouteBuilder routes)
|
||||
private static ControllerActionEndpointDataSource GetOrCreateDataSource(IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
var dataSource = routes.DataSources.OfType<ControllerActionEndpointDataSource>().FirstOrDefault();
|
||||
var dataSource = endpoints.DataSources.OfType<ControllerActionEndpointDataSource>().FirstOrDefault();
|
||||
if (dataSource == null)
|
||||
{
|
||||
dataSource = routes.ServiceProvider.GetRequiredService<ControllerActionEndpointDataSource>();
|
||||
routes.DataSources.Add(dataSource);
|
||||
dataSource = endpoints.ServiceProvider.GetRequiredService<ControllerActionEndpointDataSource>();
|
||||
endpoints.DataSources.Add(dataSource);
|
||||
}
|
||||
|
||||
return dataSource;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Core;
|
||||
using Microsoft.AspNetCore.Mvc.Routing;
|
||||
|
|
@ -18,9 +17,6 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </summary>
|
||||
public static class MvcApplicationBuilderExtensions
|
||||
{
|
||||
// Property key set in routing package by UseEndpointRouting to indicate middleware is registered
|
||||
private const string EndpointRoutingRegisteredKey = "__EndpointRoutingMiddlewareRegistered";
|
||||
|
||||
/// <summary>
|
||||
/// Adds MVC to the <see cref="IApplicationBuilder"/> request execution pipeline.
|
||||
/// </summary>
|
||||
|
|
@ -88,58 +84,23 @@ namespace Microsoft.AspNetCore.Builder
|
|||
|
||||
if (options.Value.EnableEndpointRouting)
|
||||
{
|
||||
var dataSource = app.ApplicationServices.GetRequiredService<ActionEndpointDataSource>();
|
||||
|
||||
var endpointRouteBuilder = new EndpointRouteBuilder(app);
|
||||
|
||||
configureRoutes(endpointRouteBuilder);
|
||||
|
||||
foreach (var router in endpointRouteBuilder.Routes)
|
||||
{
|
||||
// Only accept Microsoft.AspNetCore.Routing.Route when converting to endpoint
|
||||
// Sub-types could have additional customization that we can't knowingly convert
|
||||
if (router is Route route && router.GetType() == typeof(Route))
|
||||
{
|
||||
var entry = new ConventionalRouteEntry(
|
||||
route.Name,
|
||||
route.RouteTemplate,
|
||||
route.Defaults,
|
||||
route.Constraints.ToDictionary(kvp => kvp.Key, kvp => (object)kvp.Value),
|
||||
route.DataTokens);
|
||||
|
||||
dataSource.AddRoute(entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException($"Cannot use '{router.GetType().FullName}' with Endpoint Routing.");
|
||||
}
|
||||
}
|
||||
|
||||
if (!app.Properties.TryGetValue(EndpointRoutingRegisteredKey, out _))
|
||||
{
|
||||
// Matching middleware has not been registered yet
|
||||
// For back-compat register middleware so an endpoint is matched and then immediately used
|
||||
app.UseRouting(routerBuilder =>
|
||||
{
|
||||
routerBuilder.DataSources.Add(dataSource);
|
||||
});
|
||||
}
|
||||
|
||||
return app.UseEndpoint();
|
||||
var message =
|
||||
"Endpoint Routing does not support 'IApplicationBuilder.UseMvc(...)'. To use " +
|
||||
"'IApplicationBuilder.UseMvc' set 'MvcOptions.EnableEndpointRouting = false' inside " +
|
||||
"'ConfigureServices(...).";
|
||||
throw new InvalidOperationException(message);
|
||||
}
|
||||
else
|
||||
|
||||
var routes = new RouteBuilder(app)
|
||||
{
|
||||
var routes = new RouteBuilder(app)
|
||||
{
|
||||
DefaultHandler = app.ApplicationServices.GetRequiredService<MvcRouteHandler>(),
|
||||
};
|
||||
DefaultHandler = app.ApplicationServices.GetRequiredService<MvcRouteHandler>(),
|
||||
};
|
||||
|
||||
configureRoutes(routes);
|
||||
configureRoutes(routes);
|
||||
|
||||
routes.Routes.Insert(0, AttributeRouting.CreateAttributeMegaRoute(app.ApplicationServices));
|
||||
routes.Routes.Insert(0, AttributeRouting.CreateAttributeMegaRoute(app.ApplicationServices));
|
||||
|
||||
return app.UseRouter(routes.Build());
|
||||
}
|
||||
return app.UseRouter(routes.Build());
|
||||
}
|
||||
|
||||
private class EndpointRouteBuilder : IRouteBuilder
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ using Microsoft.AspNetCore.Mvc.Infrastructure;
|
|||
|
||||
namespace Microsoft.AspNetCore.Mvc.Routing
|
||||
{
|
||||
// This is only used to support the scenario where UseMvc is called with
|
||||
// EnableEndpointRouting = true. For layering reasons we can't use the PageActionEndpointDataSource
|
||||
// here.
|
||||
internal class ActionEndpointDataSource : ActionEndpointDataSourceBase
|
||||
{
|
||||
private readonly ActionEndpointFactory _endpointFactory;
|
||||
|
|
@ -22,10 +19,10 @@ namespace Microsoft.AspNetCore.Mvc.Routing
|
|||
: base(actions)
|
||||
{
|
||||
_endpointFactory = endpointFactory;
|
||||
|
||||
|
||||
_routes = new List<ConventionalRouteEntry>();
|
||||
|
||||
// IMPORTANT: this needs to be the last thing we do in the constructor.
|
||||
// IMPORTANT: this needs to be the last thing we do in the constructor.
|
||||
// Change notifications can happen immediately!
|
||||
Subscribe();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ namespace Microsoft.AspNetCore.Mvc.Core.Builder
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void UseMvc_EndpointRoutingEnabled_AddsRoute()
|
||||
public void UseMvc_EndpointRoutingEnabled_ThrowsException()
|
||||
{
|
||||
// Arrange
|
||||
var services = new ServiceCollection();
|
||||
|
|
@ -73,21 +73,21 @@ namespace Microsoft.AspNetCore.Mvc.Core.Builder
|
|||
var appBuilder = new ApplicationBuilder(serviceProvider);
|
||||
|
||||
// Act
|
||||
appBuilder.UseMvc(routes =>
|
||||
var ex = Assert.Throws<InvalidOperationException>(() =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
name: "default",
|
||||
template: "{controller=Home}/{action=Index}/{id?}");
|
||||
appBuilder.UseMvc(routes =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
name: "default",
|
||||
template: "{controller=Home}/{action=Index}/{id?}");
|
||||
});
|
||||
});
|
||||
|
||||
var routeOptions = appBuilder.ApplicationServices
|
||||
.GetRequiredService<IOptions<RouteOptions>>();
|
||||
|
||||
var dataSource = (ActionEndpointDataSource)Assert.Single(routeOptions.Value.EndpointDataSources, ds => ds is ActionEndpointDataSource);
|
||||
|
||||
var endpointInfo = Assert.Single(dataSource.Routes);
|
||||
Assert.Equal("default", endpointInfo.RouteName);
|
||||
Assert.Equal("{controller=Home}/{action=Index}/{id?}", endpointInfo.Pattern.RawText);
|
||||
var expected =
|
||||
"Endpoint Routing does not support 'IApplicationBuilder.UseMvc(...)'. To use " +
|
||||
"'IApplicationBuilder.UseMvc' set 'MvcOptions.EnableEndpointRouting = false' inside " +
|
||||
"'ConfigureServices(...).";
|
||||
Assert.Equal(expected, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ namespace Microsoft.AspNetCore.Builder
|
|||
{
|
||||
public static partial class RazorPagesEndpointRouteBuilderExtensions
|
||||
{
|
||||
public static void MapFallbackToAreaPage(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string page, string area) { }
|
||||
public static void MapFallbackToAreaPage(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, string page, string area) { }
|
||||
public static void MapFallbackToPage(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string page) { }
|
||||
public static void MapFallbackToPage(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes, string pattern, string page) { }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapRazorPages(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder routes) { throw null; }
|
||||
public static void MapFallbackToAreaPage(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string page, string area) { }
|
||||
public static void MapFallbackToAreaPage(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string pattern, string page, string area) { }
|
||||
public static void MapFallbackToPage(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string page) { }
|
||||
public static void MapFallbackToPage(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string pattern, string page) { }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapRazorPages(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints) { throw null; }
|
||||
}
|
||||
}
|
||||
namespace Microsoft.AspNetCore.Mvc.ApplicationModels
|
||||
|
|
|
|||
|
|
@ -19,18 +19,18 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// <summary>
|
||||
/// Adds endpoints for Razor Pages to the <see cref="IEndpointRouteBuilder"/>.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/>.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/>.</param>
|
||||
/// <returns>An <see cref="IEndpointConventionBuilder"/> for endpoints associated with Razor Pages.</returns>
|
||||
public static IEndpointConventionBuilder MapRazorPages(this IEndpointRouteBuilder routes)
|
||||
public static IEndpointConventionBuilder MapRazorPages(this IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
EnsureRazorPagesServices(routes);
|
||||
EnsureRazorPagesServices(endpoints);
|
||||
|
||||
return GetOrCreateDataSource(routes);
|
||||
return GetOrCreateDataSource(endpoints);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// requests for non-file-names with the lowest possible priority. The request will be routed to a page endpoint that
|
||||
/// matches <paramref name="page"/>.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="page">The page name.</param>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
|
|
@ -57,11 +57,11 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// will be available.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
public static void MapFallbackToPage(this IEndpointRouteBuilder routes, string page)
|
||||
public static void MapFallbackToPage(this IEndpointRouteBuilder endpoints, string page)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (page == null)
|
||||
|
|
@ -71,14 +71,14 @@ namespace Microsoft.AspNetCore.Builder
|
|||
|
||||
PageConventionCollection.EnsureValidPageName(page, nameof(page));
|
||||
|
||||
EnsureRazorPagesServices(routes);
|
||||
EnsureRazorPagesServices(endpoints);
|
||||
|
||||
// Called for side-effect to make sure that the data source is registered.
|
||||
GetOrCreateDataSource(routes);
|
||||
GetOrCreateDataSource(endpoints);
|
||||
|
||||
// Maps a fallback endpoint with an empty delegate. This is OK because
|
||||
// we don't expect the delegate to run.
|
||||
routes.MapFallback(context => Task.CompletedTask).Add(b =>
|
||||
endpoints.MapFallback(context => Task.CompletedTask).Add(b =>
|
||||
{
|
||||
// MVC registers a policy that looks for this metadata.
|
||||
b.Metadata.Add(CreateDynamicPageMetadata(page, area: null));
|
||||
|
|
@ -90,7 +90,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// requests for non-file-names with the lowest possible priority. The request will be routed to a page endpoint that
|
||||
/// matches <paramref name="page"/>.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="pattern">The route pattern.</param>
|
||||
/// <param name="page">The action name.</param>
|
||||
/// <remarks>
|
||||
|
|
@ -114,13 +114,13 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </para>
|
||||
/// </remarks>
|
||||
public static void MapFallbackToPage(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string pattern,
|
||||
string page)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (pattern == null)
|
||||
|
|
@ -135,14 +135,14 @@ namespace Microsoft.AspNetCore.Builder
|
|||
|
||||
PageConventionCollection.EnsureValidPageName(page, nameof(page));
|
||||
|
||||
EnsureRazorPagesServices(routes);
|
||||
EnsureRazorPagesServices(endpoints);
|
||||
|
||||
// Called for side-effect to make sure that the data source is registered.
|
||||
GetOrCreateDataSource(routes);
|
||||
GetOrCreateDataSource(endpoints);
|
||||
|
||||
// Maps a fallback endpoint with an empty delegate. This is OK because
|
||||
// we don't expect the delegate to run.
|
||||
routes.MapFallback(pattern, context => Task.CompletedTask).Add(b =>
|
||||
endpoints.MapFallback(pattern, context => Task.CompletedTask).Add(b =>
|
||||
{
|
||||
// MVC registers a policy that looks for this metadata.
|
||||
b.Metadata.Add(CreateDynamicPageMetadata(page, area: null));
|
||||
|
|
@ -154,7 +154,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// requests for non-file-names with the lowest possible priority. The request will be routed to a page endpoint that
|
||||
/// matches <paramref name="page"/>, and <paramref name="area"/>.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="page">The action name.</param>
|
||||
/// <param name="area">The area name.</param>
|
||||
/// <remarks>
|
||||
|
|
@ -175,13 +175,13 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </para>
|
||||
/// </remarks>
|
||||
public static void MapFallbackToAreaPage(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string page,
|
||||
string area)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (page == null)
|
||||
|
|
@ -191,14 +191,14 @@ namespace Microsoft.AspNetCore.Builder
|
|||
|
||||
PageConventionCollection.EnsureValidPageName(page, nameof(page));
|
||||
|
||||
EnsureRazorPagesServices(routes);
|
||||
EnsureRazorPagesServices(endpoints);
|
||||
|
||||
// Called for side-effect to make sure that the data source is registered.
|
||||
GetOrCreateDataSource(routes);
|
||||
GetOrCreateDataSource(endpoints);
|
||||
|
||||
// Maps a fallback endpoint with an empty delegate. This is OK because
|
||||
// we don't expect the delegate to run.
|
||||
routes.MapFallback(context => Task.CompletedTask).Add(b =>
|
||||
endpoints.MapFallback(context => Task.CompletedTask).Add(b =>
|
||||
{
|
||||
// MVC registers a policy that looks for this metadata.
|
||||
b.Metadata.Add(CreateDynamicPageMetadata(page, area));
|
||||
|
|
@ -210,7 +210,7 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// requests for non-file-names with the lowest possible priority. The request will be routed to a page endpoint that
|
||||
/// matches <paramref name="page"/>, and <paramref name="area"/>.
|
||||
/// </summary>
|
||||
/// <param name="routes">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
|
||||
/// <param name="pattern">The route pattern.</param>
|
||||
/// <param name="page">The action name.</param>
|
||||
/// <param name="area">The area name.</param>
|
||||
|
|
@ -235,14 +235,14 @@ namespace Microsoft.AspNetCore.Builder
|
|||
/// </para>
|
||||
/// </remarks>
|
||||
public static void MapFallbackToAreaPage(
|
||||
this IEndpointRouteBuilder routes,
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
string pattern,
|
||||
string page,
|
||||
string area)
|
||||
{
|
||||
if (routes == null)
|
||||
if (endpoints == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(routes));
|
||||
throw new ArgumentNullException(nameof(endpoints));
|
||||
}
|
||||
|
||||
if (pattern == null)
|
||||
|
|
@ -257,14 +257,14 @@ namespace Microsoft.AspNetCore.Builder
|
|||
|
||||
PageConventionCollection.EnsureValidPageName(page, nameof(page));
|
||||
|
||||
EnsureRazorPagesServices(routes);
|
||||
EnsureRazorPagesServices(endpoints);
|
||||
|
||||
// Called for side-effect to make sure that the data source is registered.
|
||||
GetOrCreateDataSource(routes);
|
||||
GetOrCreateDataSource(endpoints);
|
||||
|
||||
// Maps a fallback endpoint with an empty delegate. This is OK because
|
||||
// we don't expect the delegate to run.
|
||||
routes.MapFallback(pattern, context => Task.CompletedTask).Add(b =>
|
||||
endpoints.MapFallback(pattern, context => Task.CompletedTask).Add(b =>
|
||||
{
|
||||
// MVC registers a policy that looks for this metadata.
|
||||
b.Metadata.Add(CreateDynamicPageMetadata(page, area));
|
||||
|
|
@ -280,9 +280,9 @@ namespace Microsoft.AspNetCore.Builder
|
|||
});
|
||||
}
|
||||
|
||||
private static void EnsureRazorPagesServices(IEndpointRouteBuilder routes)
|
||||
private static void EnsureRazorPagesServices(IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
var marker = routes.ServiceProvider.GetService<PageActionEndpointDataSource>();
|
||||
var marker = endpoints.ServiceProvider.GetService<PageActionEndpointDataSource>();
|
||||
if (marker == null)
|
||||
{
|
||||
throw new InvalidOperationException(Mvc.Core.Resources.FormatUnableToFindServices(
|
||||
|
|
@ -292,13 +292,13 @@ namespace Microsoft.AspNetCore.Builder
|
|||
}
|
||||
}
|
||||
|
||||
private static PageActionEndpointDataSource GetOrCreateDataSource(IEndpointRouteBuilder routes)
|
||||
private static PageActionEndpointDataSource GetOrCreateDataSource(IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
var dataSource = routes.DataSources.OfType<PageActionEndpointDataSource>().FirstOrDefault();
|
||||
var dataSource = endpoints.DataSources.OfType<PageActionEndpointDataSource>().FirstOrDefault();
|
||||
if (dataSource == null)
|
||||
{
|
||||
dataSource = routes.ServiceProvider.GetRequiredService<PageActionEndpointDataSource>();
|
||||
routes.DataSources.Add(dataSource);
|
||||
dataSource = endpoints.ServiceProvider.GetRequiredService<PageActionEndpointDataSource>();
|
||||
endpoints.DataSources.Add(dataSource);
|
||||
}
|
||||
|
||||
return dataSource;
|
||||
|
|
|
|||
|
|
@ -155,8 +155,15 @@ namespace BasicApi
|
|||
}
|
||||
});
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseMvc();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
}
|
||||
|
||||
private void CreateDatabaseTables(IServiceProvider services)
|
||||
|
|
|
|||
|
|
@ -116,7 +116,16 @@ namespace BasicViews
|
|||
});
|
||||
|
||||
app.UseStaticFiles();
|
||||
app.UseMvcWithDefaultRoute();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
});
|
||||
}
|
||||
|
||||
private void CreateDatabaseTables(IServiceProvider services)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,13 @@ public class Startup
|
|||
|
||||
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
|
||||
{
|
||||
app.UseMvc();
|
||||
app.UseRouting();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
endpoints.MapRazorPages();
|
||||
});
|
||||
}
|
||||
|
||||
private static List<DataA> DataA = GenerateDataA();
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ namespace MvcSandbox
|
|||
app.UseDeveloperExceptionPage();
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseRouting(builder =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(builder =>
|
||||
{
|
||||
builder.MapGet(
|
||||
requestDelegate: WriteEndpoints,
|
||||
|
|
@ -73,8 +74,6 @@ namespace MvcSandbox
|
|||
builder.MapComponentHub<MvcSandbox.Components.App>("app");
|
||||
builder.MapFallbackToPage("/Components");
|
||||
});
|
||||
|
||||
app.UseEndpoint();
|
||||
}
|
||||
|
||||
private static Task WriteEndpoints(HttpContext httpContext)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
// 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.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||
{
|
||||
public class GlobalAuthorizationFilterEndpointRoutingTest : GlobalAuthorizationFilterTestBase, IClassFixture<MvcTestFixture<SecurityWebSite.StartupWithGlobalDenyAnonymousFilter>>
|
||||
{
|
||||
public GlobalAuthorizationFilterEndpointRoutingTest(MvcTestFixture<SecurityWebSite.StartupWithGlobalDenyAnonymousFilter> fixture)
|
||||
{
|
||||
Factory = fixture.Factories.FirstOrDefault() ?? fixture.WithWebHostBuilder(ConfigureWebHostBuilder);
|
||||
Client = Factory.CreateDefaultClient();
|
||||
}
|
||||
|
||||
private static void ConfigureWebHostBuilder(IWebHostBuilder builder) =>
|
||||
builder.UseStartup<SecurityWebSite.StartupWithGlobalDenyAnonymousFilter>();
|
||||
|
||||
public WebApplicationFactory<SecurityWebSite.StartupWithGlobalDenyAnonymousFilter> Factory { get; }
|
||||
|
||||
[Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/8387")]
|
||||
public override Task DeniesAnonymousUsers_ByDefault()
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,29 +5,16 @@ using System.Linq;
|
|||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||
{
|
||||
public class GlobalAuthorizationFilterTest : IClassFixture<MvcTestFixture<SecurityWebSite.StartupWithGlobalDenyAnonymousFilter>>
|
||||
public abstract class GlobalAuthorizationFilterTestBase : IClassFixture<MvcTestFixture<SecurityWebSite.StartupWithGlobalDenyAnonymousFilter>>
|
||||
{
|
||||
public GlobalAuthorizationFilterTest(MvcTestFixture<SecurityWebSite.StartupWithGlobalDenyAnonymousFilter> fixture)
|
||||
{
|
||||
Factory = fixture.Factories.FirstOrDefault() ?? fixture.WithWebHostBuilder(ConfigureWebHostBuilder);
|
||||
Client = Factory.CreateDefaultClient();
|
||||
}
|
||||
|
||||
private static void ConfigureWebHostBuilder(IWebHostBuilder builder) =>
|
||||
builder.UseStartup<SecurityWebSite.StartupWithGlobalDenyAnonymousFilter>();
|
||||
|
||||
public HttpClient Client { get; }
|
||||
|
||||
public WebApplicationFactory<SecurityWebSite.StartupWithGlobalDenyAnonymousFilter> Factory { get; }
|
||||
public HttpClient Client { get; protected set; }
|
||||
|
||||
[Fact]
|
||||
public async Task DeniesAnonymousUsers_ByDefault()
|
||||
public virtual async Task DeniesAnonymousUsers_ByDefault()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/Administration/Index");
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
// 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.Linq;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc.Testing;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||
{
|
||||
public class GlobalAuthorizationFilterUseMvcTest : GlobalAuthorizationFilterTestBase, IClassFixture<MvcTestFixture<SecurityWebSite.StartupWithGlobalDenyAnonymousFilterWithUseMvc>>
|
||||
{
|
||||
public GlobalAuthorizationFilterUseMvcTest(MvcTestFixture<SecurityWebSite.StartupWithGlobalDenyAnonymousFilterWithUseMvc> fixture)
|
||||
{
|
||||
Factory = fixture.Factories.FirstOrDefault() ?? fixture.WithWebHostBuilder(ConfigureWebHostBuilder);
|
||||
Client = Factory.CreateDefaultClient();
|
||||
}
|
||||
|
||||
private static void ConfigureWebHostBuilder(IWebHostBuilder builder) =>
|
||||
builder.UseStartup<SecurityWebSite.StartupWithGlobalDenyAnonymousFilterWithUseMvc>();
|
||||
|
||||
public WebApplicationFactory<SecurityWebSite.StartupWithGlobalDenyAnonymousFilterWithUseMvc> Factory { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -918,7 +918,7 @@ Hello from /Pages/WithViewStart/Index.cshtml!";
|
|||
{
|
||||
// Arrange
|
||||
var expected =
|
||||
@"Microsoft.AspNetCore.Mvc.Routing.EndpointRoutingUrlHelper
|
||||
@"Microsoft.AspNetCore.Mvc.Routing.UrlHelper
|
||||
Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper`1[AspNetCore.InjectedPageProperties]
|
||||
Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary`1[AspNetCore.InjectedPageProperties]";
|
||||
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
Assert.Equal("Hello from /Admin/RouteTemplate my-user-id 4", content.Trim());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/8387")]
|
||||
public async Task AuthConvention_IsAppliedOnBasePathRelativePaths_ForFiles()
|
||||
{
|
||||
// Act
|
||||
|
|
@ -104,7 +104,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
Assert.Equal("/Login?ReturnUrl=%2FConventions%2FAuth", response.Headers.Location.PathAndQuery);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/8387")]
|
||||
public async Task AuthConvention_IsAppliedOnBasePathRelativePaths_For_Folders()
|
||||
{
|
||||
// Act
|
||||
|
|
@ -372,7 +372,7 @@ Hello from /Pages/Shared/";
|
|||
Assert.Equal(expected, response.Trim(), ignoreLineEndingDifferences: true);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/8387")]
|
||||
public async Task AuthorizeFolderConvention_CanBeAppliedToAreaPages()
|
||||
{
|
||||
// Act
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
|
||||
public HttpClient Client { get; }
|
||||
|
||||
[Fact]
|
||||
[Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/8387")]
|
||||
public async Task Authorize_AppliedUsingConvention_Works()
|
||||
{
|
||||
// Act
|
||||
|
|
@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
|||
Assert.Equal("Hello from Anonymous", content.Trim());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Fact(Skip = "https://github.com/aspnet/AspNetCore/issues/8387")]
|
||||
public async Task Authorize_AppliedUsingAttributeOnModel_Works()
|
||||
{
|
||||
// Act
|
||||
|
|
|
|||
|
|
@ -1,386 +0,0 @@
|
|||
// 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.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.FunctionalTests
|
||||
{
|
||||
public class RoutingUseMvcWithEndpointRoutingTest : RoutingTestsBase<RoutingWebSite.StartupWithUseMvcAndEndpointRouting>
|
||||
{
|
||||
public RoutingUseMvcWithEndpointRoutingTest(MvcTestFixture<RoutingWebSite.StartupWithUseMvcAndEndpointRouting> fixture)
|
||||
: base(fixture)
|
||||
{
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AttributeRoutedAction_ContainsPage_RouteMatched()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/PageRoute/Attribute/pagevalue");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
|
||||
|
||||
Assert.Contains("/PageRoute/Attribute/pagevalue", result.ExpectedUrls);
|
||||
Assert.Equal("PageRoute", result.Controller);
|
||||
Assert.Equal("AttributeRoute", result.Action);
|
||||
|
||||
Assert.Contains(
|
||||
new KeyValuePair<string, object>("page", "pagevalue"),
|
||||
result.RouteValues);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ParameterTransformer_TokenReplacement_Found()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/parameter-transformer/my-action");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
|
||||
|
||||
Assert.Equal("ParameterTransformer", result.Controller);
|
||||
Assert.Equal("MyAction", result.Action);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ParameterTransformer_TokenReplacement_NotFound()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/ParameterTransformer/MyAction");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AttributeRoutedAction_Parameters_Found()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/EndpointRouting/Index");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
|
||||
|
||||
Assert.Equal("EndpointRouting", result.Controller);
|
||||
Assert.Equal("Index", result.Action);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AttributeRoutedAction_Parameters_DefaultValue_Found()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/EndpointRouting");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
|
||||
|
||||
Assert.Equal("EndpointRouting", result.Controller);
|
||||
Assert.Equal("Index", result.Action);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AttributeRoutedAction_ParameterTransformer_Found()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/endpoint-routing/ParameterTransformer");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
|
||||
|
||||
Assert.Equal("EndpointRouting", result.Controller);
|
||||
Assert.Equal("ParameterTransformer", result.Action);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AttributeRoutedAction_ParameterTransformer_NotFound()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/EndpointRouting/ParameterTransformer");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AttributeRoutedAction_ParameterTransformer_LinkToSelf()
|
||||
{
|
||||
// Arrange
|
||||
var url = LinkFrom("http://localhost/endpoint-routing/ParameterTransformer").To(new { });
|
||||
|
||||
// Act
|
||||
var response = await Client.GetAsync(url);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
|
||||
|
||||
Assert.Equal("EndpointRouting", result.Controller);
|
||||
Assert.Equal("ParameterTransformer", result.Action);
|
||||
|
||||
Assert.Equal("/endpoint-routing/ParameterTransformer", result.Link);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AttributeRoutedAction_ParameterTransformer_LinkWithAmbientController()
|
||||
{
|
||||
// Arrange
|
||||
var url = LinkFrom("http://localhost/endpoint-routing/ParameterTransformer").To(new { action = "Get", id = 5 });
|
||||
|
||||
// Act
|
||||
var response = await Client.GetAsync(url);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
|
||||
|
||||
Assert.Equal("EndpointRouting", result.Controller);
|
||||
Assert.Equal("ParameterTransformer", result.Action);
|
||||
|
||||
Assert.Equal("/endpoint-routing/5", result.Link);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AttributeRoutedAction_ParameterTransformer_LinkToAttributeRoutedController()
|
||||
{
|
||||
// Arrange
|
||||
var url = LinkFrom("http://localhost/endpoint-routing/ParameterTransformer").To(new { action = "ShowPosts", controller = "Blog" });
|
||||
|
||||
// Act
|
||||
var response = await Client.GetAsync(url);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
|
||||
|
||||
Assert.Equal("EndpointRouting", result.Controller);
|
||||
Assert.Equal("ParameterTransformer", result.Action);
|
||||
|
||||
Assert.Equal("/Blog/ShowPosts", result.Link);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task AttributeRoutedAction_ParameterTransformer_LinkToConventionalController()
|
||||
{
|
||||
// Arrange
|
||||
var url = LinkFrom("http://localhost/endpoint-routing/ParameterTransformer").To(new { action = "Index", controller = "Home" });
|
||||
|
||||
// Act
|
||||
var response = await Client.GetAsync(url);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
|
||||
|
||||
Assert.Equal("EndpointRouting", result.Controller);
|
||||
Assert.Equal("ParameterTransformer", result.Action);
|
||||
|
||||
Assert.Equal("/", result.Link);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async override Task HasEndpointMatch()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/Routing/HasEndpointMatch");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<bool>(body);
|
||||
|
||||
Assert.True(result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async override Task RouteData_Routers_ConventionalRoute()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/RouteData/Conventional");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<ResultData>(body);
|
||||
|
||||
Assert.Equal(
|
||||
Array.Empty<string>(),
|
||||
result.Routers);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async override Task RouteData_Routers_AttributeRoute()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/RouteData/Attribute");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<ResultData>(body);
|
||||
|
||||
Assert.Equal(
|
||||
Array.Empty<string>(),
|
||||
result.Routers);
|
||||
}
|
||||
|
||||
// Endpoint routing exposes HTTP 405s for HTTP method mismatches
|
||||
[Fact]
|
||||
public override async Task ConventionalRoutedController_InArea_ActionBlockedByHttpMethod()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/Travel/Flight/BuyTickets");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.MethodNotAllowed, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ConventionalRoutedAction_ParameterTransformer()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/ConventionalTransformerRoute/conventional-transformer/Index");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
|
||||
|
||||
Assert.Equal("ConventionalTransformer", result.Controller);
|
||||
Assert.Equal("Index", result.Action);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ConventionalRoutedAction_ParameterTransformer_NotFound()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/ConventionalTransformerRoute/ConventionalTransformer/Index");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ConventionalRoutedAction_ParameterTransformer_DefaultValue()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/ConventionalTransformerRoute/conventional-transformer");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
|
||||
|
||||
Assert.Equal("ConventionalTransformer", result.Controller);
|
||||
Assert.Equal("Index", result.Action);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ConventionalRoutedAction_ParameterTransformer_WithParam()
|
||||
{
|
||||
// Arrange & Act
|
||||
var response = await Client.GetAsync("http://localhost/ConventionalTransformerRoute/conventional-transformer/Param/my-value");
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
|
||||
|
||||
Assert.Equal("ConventionalTransformer", result.Controller);
|
||||
Assert.Equal("Param", result.Action);
|
||||
|
||||
Assert.Equal("/ConventionalTransformerRoute/conventional-transformer/Param/my-value", Assert.Single(result.ExpectedUrls));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ConventionalRoutedAction_ParameterTransformer_LinkToConventionalController()
|
||||
{
|
||||
// Arrange
|
||||
var url = LinkFrom("http://localhost/ConventionalTransformerRoute/conventional-transformer/Index").To(new { action = "Index", controller = "Home" });
|
||||
|
||||
// Act
|
||||
var response = await Client.GetAsync(url);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
|
||||
|
||||
Assert.Equal("ConventionalTransformer", result.Controller);
|
||||
Assert.Equal("Index", result.Action);
|
||||
Assert.Equal("/", result.Link);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ConventionalRoutedAction_ParameterTransformer_LinkToConventionalControllerWithParam()
|
||||
{
|
||||
// Arrange
|
||||
var url = LinkFrom("http://localhost/ConventionalTransformerRoute/conventional-transformer/Index").To(new { action = "Param", controller = "ConventionalTransformer", param = "MyValue" });
|
||||
|
||||
// Act
|
||||
var response = await Client.GetAsync(url);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
|
||||
|
||||
Assert.Equal("ConventionalTransformer", result.Controller);
|
||||
Assert.Equal("Index", result.Action);
|
||||
Assert.Equal("/ConventionalTransformerRoute/conventional-transformer/Param/my-value", result.Link);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ConventionalRoutedAction_ParameterTransformer_LinkToSelf()
|
||||
{
|
||||
// Arrange
|
||||
var url = LinkFrom("http://localhost/ConventionalTransformerRoute/conventional-transformer/Index").To(new {});
|
||||
|
||||
// Act
|
||||
var response = await Client.GetAsync(url);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
|
||||
var body = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<RoutingResult>(body);
|
||||
|
||||
Assert.Equal("ConventionalTransformer", result.Controller);
|
||||
Assert.Equal("Index", result.Action);
|
||||
Assert.Equal("/ConventionalTransformerRoute/conventional-transformer", result.Link);
|
||||
}
|
||||
|
||||
// Endpoint routing exposes HTTP 405s for HTTP method mismatches.
|
||||
protected override void AssertCorsRejectionStatusCode(HttpResponseMessage response)
|
||||
{
|
||||
Assert.Equal(HttpStatusCode.MethodNotAllowed, response.StatusCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -46,9 +46,10 @@ namespace ApiExplorerWebSite
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapDefaultControllerRoute();
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,12 +27,13 @@ namespace ApplicationModelWebSite
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapControllerRoute(name: "areaRoute", pattern: "{area:exists}/{controller=Home}/{action=Index}");
|
||||
routes.MapControllerRoute(name: "default", pattern: "{controller}/{action}/{id?}");
|
||||
endpoints.MapControllerRoute(name: "areaRoute", pattern: "{area:exists}/{controller=Home}/{action=Index}");
|
||||
endpoints.MapControllerRoute(name: "default", pattern: "{controller}/{action}/{id?}");
|
||||
|
||||
routes.MapRazorPages();
|
||||
endpoints.MapRazorPages();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,14 +35,15 @@ namespace BasicWebSite
|
|||
// Initializes the RequestId service for each request
|
||||
app.UseMiddleware<RequestIdMiddleware>();
|
||||
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapControllerRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "ActionAsMethod",
|
||||
pattern: "{controller}/{action}",
|
||||
defaults: new { controller = "Home", action = "Index" });
|
||||
|
||||
routes.MapControllerRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "PageRoute",
|
||||
pattern: "{controller}/{action}/{page}");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -39,10 +39,11 @@ namespace BasicWebSite
|
|||
return next();
|
||||
});
|
||||
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapDefaultControllerRoute();
|
||||
routes.MapRazorPages();
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
endpoints.MapRazorPages();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,11 +28,11 @@ namespace BasicWebSite
|
|||
app.UseDeveloperExceptionPage();
|
||||
|
||||
app.UseCookiePolicy();
|
||||
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapDefaultControllerRoute();
|
||||
routes.MapRazorPages();
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
endpoints.MapRazorPages();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,9 +48,10 @@ namespace BasicWebSite
|
|||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapControllers();
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,10 +26,11 @@ namespace BasicWebSite
|
|||
app.UseDeveloperExceptionPage();
|
||||
app.UseSession();
|
||||
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapDefaultControllerRoute();
|
||||
routes.MapRazorPages();
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
endpoints.MapRazorPages();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,9 +64,10 @@ namespace ControllersFromServicesWebSite
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapDefaultControllerRoute();
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,9 +74,10 @@ namespace CorsWebSite
|
|||
|
||||
public virtual void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapControllers();
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,9 +22,10 @@ namespace ErrorPageMiddlewareWebSite
|
|||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapControllers();
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,4 +16,5 @@ type Startup () =
|
|||
member this.Configure(app: IApplicationBuilder) =
|
||||
app.UseDeveloperExceptionPage() |> ignore
|
||||
app.UseStaticFiles() |> ignore
|
||||
app.UseMvcWithDefaultRoute() |> ignore
|
||||
app.UseRouting() |> ignore
|
||||
app.UseEndpoints(fun endpoints -> endpoints.MapDefaultControllerRoute() |> ignore) |> ignore
|
||||
|
|
|
|||
|
|
@ -21,9 +21,10 @@ namespace FilesWebSite
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapDefaultControllerRoute();
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,9 +26,10 @@ namespace FormatterWebSite
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapDefaultControllerRoute();
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,9 +23,10 @@ namespace FormatterWebSite
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapDefaultControllerRoute();
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,9 +19,10 @@ namespace FormatterWebSite
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapDefaultControllerRoute();
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,17 +40,18 @@ namespace GenericHostWebSite
|
|||
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapControllerRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
"areaRoute",
|
||||
"{area:exists}/{controller}/{action}",
|
||||
new { controller = "Home", action = "Index" });
|
||||
|
||||
routes.MapControllerRoute("ActionAsMethod", "{controller}/{action}",
|
||||
endpoints.MapControllerRoute("ActionAsMethod", "{controller}/{action}",
|
||||
defaults: new { controller = "Home", action = "Index" });
|
||||
|
||||
routes.MapControllerRoute("PageRoute", "{controller}/{action}/{page}");
|
||||
endpoints.MapControllerRoute("PageRoute", "{controller}/{action}/{page}");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,22 +30,23 @@ namespace HtmlGenerationWebSite
|
|||
{
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapControllerRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "areaRoute",
|
||||
pattern: "{area:exists}/{controller}/{action}/{id?}",
|
||||
defaults: new { action = "Index" });
|
||||
routes.MapControllerRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "productRoute",
|
||||
pattern: "Product/{action}",
|
||||
defaults: new { controller = "Product" });
|
||||
routes.MapControllerRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
name: "default",
|
||||
pattern: "{controller}/{action}/{id?}",
|
||||
defaults: new { controller = "HtmlGeneration_Home", action = "Index" });
|
||||
|
||||
routes.MapRazorPages();
|
||||
endpoints.MapRazorPages();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,10 +23,11 @@ namespace RazorBuildWebSite
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapDefaultControllerRoute();
|
||||
routes.MapRazorPages();
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
endpoints.MapRazorPages();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,13 +25,16 @@ namespace RazorPagesWebSite
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
{
|
||||
routes.MapControllers();
|
||||
routes.MapRazorPages();
|
||||
});
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
endpoints.MapRazorPages();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,14 +38,17 @@ namespace RazorPagesWebSite
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseAuthentication();
|
||||
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapControllerRoute("areaRoute", "{area:exists}/{controller=Home}/{action=Index}");
|
||||
routes.MapRazorPages();
|
||||
endpoints.MapControllerRoute("areaRoute", "{area:exists}/{controller=Home}/{action=Index}");
|
||||
endpoints.MapRazorPages();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ namespace RazorPagesWebSite
|
|||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options => options.LoginPath = "/Login");
|
||||
services.AddMvc()
|
||||
services.AddMvc(options => options.EnableEndpointRouting = false)
|
||||
.AddMvcLocalization()
|
||||
.AddNewtonsoftJson()
|
||||
.AddRazorPagesOptions(options =>
|
||||
|
|
|
|||
|
|
@ -45,6 +45,9 @@ namespace RazorWebSite
|
|||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseRequestLocalization(new RequestLocalizationOptions
|
||||
{
|
||||
DefaultRequestCulture = new RequestCulture("en-GB", "en-US"),
|
||||
|
|
@ -62,10 +65,10 @@ namespace RazorWebSite
|
|||
}
|
||||
});
|
||||
|
||||
app.UseRouting(routes =>
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapDefaultControllerRoute();
|
||||
routes.MapRazorPages();
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
endpoints.MapRazorPages();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,10 @@ namespace RazorWebSite
|
|||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.UseRequestLocalization(new RequestLocalizationOptions
|
||||
{
|
||||
DefaultRequestCulture = new RequestCulture("en-US", "en-US"),
|
||||
|
|
@ -44,11 +48,10 @@ namespace RazorWebSite
|
|||
new CultureInfo("en-US")
|
||||
}
|
||||
});
|
||||
app.UseStaticFiles();
|
||||
|
||||
app.UseRouting(routes =>
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapDefaultControllerRoute();
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||
|
|
|
|||
|
|
@ -38,62 +38,63 @@ namespace RoutingWebSite
|
|||
|
||||
public virtual void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapControllerRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
"NonParameterConstraintRoute",
|
||||
"NonParameterConstraintRoute/{controller}/{action}",
|
||||
defaults: null,
|
||||
constraints: new { controller = "NonParameterConstraint", nonParameter = new QueryStringConstraint() });
|
||||
|
||||
routes.MapControllerRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
"DataTokensRoute",
|
||||
"DataTokensRoute/{controller}/{action}",
|
||||
defaults: null,
|
||||
constraints: new { controller = "DataTokens" },
|
||||
dataTokens: new { hasDataTokens = true });
|
||||
|
||||
routes.MapControllerRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
"ConventionalTransformerRoute",
|
||||
"ConventionalTransformerRoute/{controller:slugify}/{action=Index}/{param:slugify?}",
|
||||
defaults: null,
|
||||
constraints: new { controller = "ConventionalTransformer" });
|
||||
|
||||
routes.MapControllerRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
"DefaultValuesRoute_OptionalParameter",
|
||||
"DefaultValuesRoute/Optional/{controller=DEFAULTVALUES}/{action=OPTIONALPARAMETER}/{id?}/{**catchAll}",
|
||||
defaults: null,
|
||||
constraints: new { controller = "DefaultValues", action = "OptionalParameter" });
|
||||
|
||||
routes.MapControllerRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
"DefaultValuesRoute_DefaultParameter",
|
||||
"DefaultValuesRoute/Default/{controller=DEFAULTVALUES}/{action=DEFAULTPARAMETER}/{id=17}/{**catchAll}",
|
||||
defaults: null,
|
||||
constraints: new { controller = "DefaultValues", action = "DefaultParameter" });
|
||||
|
||||
routes.MapAreaControllerRoute(
|
||||
endpoints.MapAreaControllerRoute(
|
||||
"flightRoute",
|
||||
"adminRoute",
|
||||
"{area:exists}/{controller}/{action}",
|
||||
defaults: new { controller = "Home", action = "Index" },
|
||||
constraints: new { area = "Travel" });
|
||||
|
||||
routes.MapControllerRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
"PageRoute",
|
||||
"{controller}/{action}/{page}",
|
||||
defaults: null,
|
||||
constraints: new { controller = "PageRoute" });
|
||||
|
||||
routes.MapControllerRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
"ActionAsMethod",
|
||||
"{controller}/{action}",
|
||||
defaults: new { controller = "Home", action = "Index" });
|
||||
|
||||
routes.MapControllerRoute(
|
||||
endpoints.MapControllerRoute(
|
||||
"RouteWithOptionalSegment",
|
||||
"{controller}/{action}/{path?}");
|
||||
|
||||
routes.MapRazorPages();
|
||||
endpoints.MapRazorPages();
|
||||
});
|
||||
|
||||
app.Map("/afterrouting", b => b.Run(c =>
|
||||
|
|
|
|||
|
|
@ -25,15 +25,16 @@ namespace RoutingWebSite
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
// Workaround for #8130
|
||||
//
|
||||
// You can't fallback to this unless it already has another route.
|
||||
routes.MapAreaControllerRoute("admin", "Admin", "Admin/{controller=Home}/{action=Index}/{id?}");
|
||||
endpoints.MapAreaControllerRoute("admin", "Admin", "Admin/{controller=Home}/{action=Index}/{id?}");
|
||||
|
||||
routes.MapFallbackToAreaController("admin/{*path:nonfile}", "Index", "Fallback", "Admin");
|
||||
routes.MapFallbackToPage("/FallbackPage");
|
||||
endpoints.MapFallbackToAreaController("admin/{*path:nonfile}", "Index", "Fallback", "Admin");
|
||||
endpoints.MapFallbackToPage("/FallbackPage");
|
||||
});
|
||||
|
||||
app.Map("/afterrouting", b => b.Run(c =>
|
||||
|
|
|
|||
|
|
@ -39,10 +39,11 @@ namespace RoutingWebSite
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseRouting(routes =>
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapDefaultControllerRoute();
|
||||
routes.MapRazorPages();
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
endpoints.MapRazorPages();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,80 +0,0 @@
|
|||
// 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.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Abstractions;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
|
||||
namespace RoutingWebSite
|
||||
{
|
||||
public class StartupWithUseMvcAndEndpointRouting : Startup
|
||||
{
|
||||
public override void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseMvc(routes =>
|
||||
{
|
||||
routes.MapRoute(
|
||||
"NonParameterConstraintRoute",
|
||||
"NonParameterConstraintRoute/{controller}/{action}",
|
||||
defaults: null,
|
||||
constraints: new { controller = "NonParameterConstraint", nonParameter = new QueryStringConstraint() });
|
||||
|
||||
routes.MapRoute(
|
||||
"DataTokensRoute",
|
||||
"DataTokensRoute/{controller}/{action}",
|
||||
defaults: null,
|
||||
constraints: new { controller = "DataTokens" },
|
||||
dataTokens: new { hasDataTokens = true });
|
||||
|
||||
routes.MapRoute(
|
||||
"ConventionalTransformerRoute",
|
||||
"ConventionalTransformerRoute/{controller:slugify}/{action=Index}/{param:slugify?}",
|
||||
defaults: null,
|
||||
constraints: new { controller = "ConventionalTransformer" });
|
||||
|
||||
routes.MapRoute(
|
||||
"DefaultValuesRoute_OptionalParameter",
|
||||
"DefaultValuesRoute/Optional/{controller=DEFAULTVALUES}/{action=OPTIONALPARAMETER}/{id?}/{**catchAll}",
|
||||
defaults: null,
|
||||
constraints: new { controller = "DefaultValues", action = "OptionalParameter" });
|
||||
|
||||
routes.MapRoute(
|
||||
"DefaultValuesRoute_DefaultParameter",
|
||||
"DefaultValuesRoute/Default/{controller=DEFAULTVALUES}/{action=DEFAULTPARAMETER}/{id=17}/{**catchAll}",
|
||||
defaults: null,
|
||||
constraints: new { controller = "DefaultValues", action = "DefaultParameter" });
|
||||
|
||||
routes.MapAreaRoute(
|
||||
"flightRoute",
|
||||
"adminRoute",
|
||||
"{area:exists}/{controller}/{action}",
|
||||
defaults: new { controller = "Home", action = "Index" },
|
||||
constraints: new { area = "Travel" });
|
||||
|
||||
routes.MapRoute(
|
||||
"PageRoute",
|
||||
"{controller}/{action}/{page}",
|
||||
defaults: null,
|
||||
constraints: new { controller = "PageRoute" });
|
||||
|
||||
routes.MapRoute(
|
||||
"ActionAsMethod",
|
||||
"{controller}/{action}",
|
||||
defaults: new { controller = "Home", action = "Index" });
|
||||
|
||||
routes.MapRoute(
|
||||
"RouteWithOptionalSegment",
|
||||
"{controller}/{action}/{path?}");
|
||||
});
|
||||
|
||||
app.Map("/afterrouting", b => b.Run(c =>
|
||||
{
|
||||
return c.Response.WriteAsync("Hello from middleware after routing");
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ namespace SecurityWebSite
|
|||
services.AddMvc()
|
||||
.SetCompatibilityVersion(CompatibilityVersion.Latest);
|
||||
services.AddAntiforgery();
|
||||
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
|
||||
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
|
||||
{
|
||||
options.LoginPath = "/Home/Login";
|
||||
options.LogoutPath = "/Home/Logout";
|
||||
|
|
@ -30,11 +30,14 @@ namespace SecurityWebSite
|
|||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseAuthentication();
|
||||
app.UseRouting();
|
||||
|
||||
app.UseRouting(routes =>
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapDefaultControllerRoute();
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,11 +33,14 @@ namespace SecurityWebSite
|
|||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseAuthentication();
|
||||
app.UseRouting();
|
||||
|
||||
app.UseRouting(routes =>
|
||||
app.UseAuthentication();
|
||||
app.UseAuthorization();
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
routes.MapDefaultControllerRoute();
|
||||
endpoints.MapDefaultControllerRoute();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authorization.Policy;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Authorization;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace SecurityWebSite
|
||||
{
|
||||
public class StartupWithGlobalDenyAnonymousFilterWithUseMvc
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services
|
||||
.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
||||
.AddCookie(options =>
|
||||
{
|
||||
options.LoginPath = "/Home/Login";
|
||||
options.LogoutPath = "/Home/Logout";
|
||||
}).AddCookie("Cookie2");
|
||||
|
||||
services.AddMvc(o =>
|
||||
{
|
||||
o.EnableEndpointRouting = false;
|
||||
o.Filters.Add(new AuthorizeFilter());
|
||||
})
|
||||
.SetCompatibilityVersion(CompatibilityVersion.Latest);
|
||||
|
||||
services.AddScoped<IPolicyEvaluator, CountingPolicyEvaluator>();
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseAuthentication();
|
||||
|
||||
app.UseMvcWithDefaultRoute();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// 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.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authorization.Policy;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace SecurityWebSite
|
||||
{
|
||||
public class StartupWithUseMvc
|
||||
{
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
// Add framework services.
|
||||
services.AddMvc(options => options.EnableEndpointRouting = false)
|
||||
.SetCompatibilityVersion(CompatibilityVersion.Latest);
|
||||
services.AddAntiforgery();
|
||||
services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(options =>
|
||||
{
|
||||
options.LoginPath = "/Home/Login";
|
||||
options.LogoutPath = "/Home/Logout";
|
||||
}).AddCookie("Cookie2");
|
||||
|
||||
services.AddScoped<IPolicyEvaluator, CountingPolicyEvaluator>();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app)
|
||||
{
|
||||
app.UseAuthentication();
|
||||
app.UseMvcWithDefaultRoute();
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue