Skip to content

Commit 575aa50

Browse files
author
John Luo
committed
Update ExceptionHandler middleware pipenline construction to reinvoke UseRouting in error branch
1 parent a8cd189 commit 575aa50

File tree

3 files changed

+75
-4
lines changed

3 files changed

+75
-4
lines changed

src/DefaultBuilder/src/WebApplicationBuilder.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,13 @@ private void ConfigureApplication(WebHostBuilderContext context, IApplicationBui
167167
if (targetRouteBuilder is null)
168168
{
169169
// The app defined endpoints without calling UseRouting() explicitly, so call UseRouting() implicitly.
170-
app.UseRouting();
170+
app.UseRouting(overrideEndpointRouteBuilder: false);
171+
172+
// Copy the endpoint route builder to the built application
173+
foreach (var item in app.Properties)
174+
{
175+
_builtApplication.Properties[item.Key] = item.Value;
176+
}
171177

172178
// An implicitly created IEndpointRouteBuilder was addeded to app.Properties by the UseRouting() call above.
173179
targetRouteBuilder = GetEndpointRouteBuilder(app)!;

src/Http/Routing/src/Builder/EndpointRoutingApplicationBuilderExtensions.cs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,56 @@ public static IApplicationBuilder UseRouting(this IApplicationBuilder builder)
4242
throw new ArgumentNullException(nameof(builder));
4343
}
4444

45+
return UseRouting(builder, true);
46+
}
47+
48+
/// <summary>
49+
/// Adds a <see cref="EndpointRoutingMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>.
50+
/// </summary>
51+
/// <param name="builder">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
52+
/// <param name="overrideEndpointRouteBuilder">Whether a new <see cref="EndpointRouteBuilder"/> should be created.</param>
53+
/// <returns>A reference to this instance after the operation has completed.</returns>
54+
/// <remarks>
55+
/// <para>
56+
/// A call to <see cref="UseRouting(IApplicationBuilder)"/> must be followed by a call to
57+
/// <see cref="UseEndpoints(IApplicationBuilder, Action{IEndpointRouteBuilder})"/> for the same <see cref="IApplicationBuilder"/>
58+
/// instance.
59+
/// </para>
60+
/// <para>
61+
/// The <see cref="EndpointRoutingMiddleware"/> defines a point in the middleware pipeline where routing decisions are
62+
/// made, and an <see cref="Endpoint"/> is associated with the <see cref="HttpContext"/>. The <see cref="EndpointMiddleware"/>
63+
/// defines a point in the middleware pipeline where the current <see cref="Endpoint"/> is executed. Middleware between
64+
/// the <see cref="EndpointRoutingMiddleware"/> and <see cref="EndpointMiddleware"/> may observe or change the
65+
/// <see cref="Endpoint"/> associated with the <see cref="HttpContext"/>.
66+
/// </para>
67+
/// </remarks>
68+
public static IApplicationBuilder UseRouting(this IApplicationBuilder builder, bool overrideEndpointRouteBuilder)
69+
{
70+
if (builder == null)
71+
{
72+
throw new ArgumentNullException(nameof(builder));
73+
}
74+
4575
VerifyRoutingServicesAreRegistered(builder);
4676

47-
var endpointRouteBuilder = new DefaultEndpointRouteBuilder(builder);
48-
builder.Properties[EndpointRouteBuilder] = endpointRouteBuilder;
77+
IEndpointRouteBuilder endpointRouteBuilder;
78+
if (overrideEndpointRouteBuilder)
79+
{
80+
endpointRouteBuilder = new DefaultEndpointRouteBuilder(builder);
81+
builder.Properties[EndpointRouteBuilder] = endpointRouteBuilder;
82+
}
83+
else
84+
{
85+
if (builder.Properties.TryGetValue(EndpointRouteBuilder, out var routeBuilder))
86+
{
87+
endpointRouteBuilder = (IEndpointRouteBuilder)routeBuilder!;
88+
}
89+
else
90+
{
91+
endpointRouteBuilder = new DefaultEndpointRouteBuilder(builder);
92+
builder.Properties[EndpointRouteBuilder] = endpointRouteBuilder;
93+
}
94+
}
4995

5096
return builder.UseMiddleware<EndpointRoutingMiddleware>(endpointRouteBuilder);
5197
}

src/Middleware/Diagnostics/src/ExceptionHandler/ExceptionHandlerExtensions.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using System.Diagnostics;
56
using Microsoft.AspNetCore.Diagnostics;
67
using Microsoft.AspNetCore.Http;
8+
using Microsoft.AspNetCore.Routing;
9+
using Microsoft.Extensions.DependencyInjection;
10+
using Microsoft.Extensions.Logging;
711
using Microsoft.Extensions.Options;
812

913
namespace Microsoft.AspNetCore.Builder
@@ -95,7 +99,22 @@ public static IApplicationBuilder UseExceptionHandler(this IApplicationBuilder a
9599
throw new ArgumentNullException(nameof(options));
96100
}
97101

98-
return app.UseMiddleware<ExceptionHandlerMiddleware>(Options.Create(options));
102+
return app.Use(next =>
103+
{
104+
var loggerFactory = app.ApplicationServices.GetRequiredService<ILoggerFactory>();
105+
var diagnosticListener = app.ApplicationServices.GetRequiredService<DiagnosticListener>();
106+
var endpointDataSource = app.ApplicationServices.GetRequiredService<EndpointDataSource>();
107+
108+
if (!string.IsNullOrEmpty(options.ExceptionHandlingPath) && options.ExceptionHandler is null)
109+
{
110+
var errorBuilder = app.New();
111+
errorBuilder.UseRouting(overrideEndpointRouteBuilder: false);
112+
errorBuilder.Run(next);
113+
options.ExceptionHandler = errorBuilder.Build();
114+
}
115+
116+
return new ExceptionHandlerMiddleware(next, loggerFactory, Options.Create(options), diagnosticListener).Invoke;
117+
});
99118
}
100119
}
101120
}

0 commit comments

Comments
 (0)