@@ -205,5 +205,86 @@ public static MinimalActionEndpointConventionBuilder Map(
205
205
206
206
return new MinimalActionEndpointConventionBuilder ( dataSource . AddEndpointBuilder ( builder ) ) ;
207
207
}
208
+
209
+ /// <summary>
210
+ /// Adds a specialized <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that will match
211
+ /// requests for non-file-names with the lowest possible priority.
212
+ /// </summary>
213
+ /// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
214
+ /// <param name="action">The delegate executed when the endpoint is matched.</param>
215
+ /// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
216
+ /// <remarks>
217
+ /// <para>
218
+ /// <see cref="MapFallback(IEndpointRouteBuilder, Delegate)"/> is intended to handle cases where URL path of
219
+ /// the request does not contain a file name, and no other endpoint has matched. This is convenient for routing
220
+ /// requests for dynamic content to a SPA framework, while also allowing requests for non-existent files to
221
+ /// result in an HTTP 404.
222
+ /// </para>
223
+ /// <para>
224
+ /// <see cref="MapFallback(IEndpointRouteBuilder, Delegate)"/> registers an endpoint using the pattern
225
+ /// <c>{*path:nonfile}</c>. The order of the registered endpoint will be <c>int.MaxValue</c>.
226
+ /// </para>
227
+ /// </remarks>
228
+ public static MinimalActionEndpointConventionBuilder MapFallback ( this IEndpointRouteBuilder endpoints , Delegate action )
229
+ {
230
+ if ( endpoints == null )
231
+ {
232
+ throw new ArgumentNullException ( nameof ( endpoints ) ) ;
233
+ }
234
+
235
+ if ( action == null )
236
+ {
237
+ throw new ArgumentNullException ( nameof ( action ) ) ;
238
+ }
239
+
240
+ return endpoints . MapFallback ( "{*path:nonfile}" , action ) ;
241
+ }
242
+
243
+ /// <summary>
244
+ /// Adds a specialized <see cref="RouteEndpoint"/> to the <see cref="IEndpointRouteBuilder"/> that will match
245
+ /// the provided pattern with the lowest possible priority.
246
+ /// </summary>
247
+ /// <param name="endpoints">The <see cref="IEndpointRouteBuilder"/> to add the route to.</param>
248
+ /// <param name="pattern">The route pattern.</param>
249
+ /// <param name="action">The delegate executed when the endpoint is matched.</param>
250
+ /// <returns>A <see cref="IEndpointConventionBuilder"/> that can be used to further customize the endpoint.</returns>
251
+ /// <remarks>
252
+ /// <para>
253
+ /// <see cref="MapFallback(IEndpointRouteBuilder, string, Delegate)"/> is intended to handle cases where no
254
+ /// other endpoint has matched. This is convenient for routing requests to a SPA framework.
255
+ /// </para>
256
+ /// <para>
257
+ /// The order of the registered endpoint will be <c>int.MaxValue</c>.
258
+ /// </para>
259
+ /// <para>
260
+ /// This overload will use the provided <paramref name="pattern"/> verbatim. Use the <c>:nonfile</c> route constraint
261
+ /// to exclude requests for static files.
262
+ /// </para>
263
+ /// </remarks>
264
+ public static MinimalActionEndpointConventionBuilder MapFallback (
265
+ this IEndpointRouteBuilder endpoints ,
266
+ string pattern ,
267
+ Delegate action )
268
+ {
269
+ if ( endpoints == null )
270
+ {
271
+ throw new ArgumentNullException ( nameof ( endpoints ) ) ;
272
+ }
273
+
274
+ if ( pattern == null )
275
+ {
276
+ throw new ArgumentNullException ( nameof ( pattern ) ) ;
277
+ }
278
+
279
+ if ( action == null )
280
+ {
281
+ throw new ArgumentNullException ( nameof ( action ) ) ;
282
+ }
283
+
284
+ var conventionBuilder = endpoints . Map ( pattern , action ) ;
285
+ conventionBuilder . WithDisplayName ( "Fallback " + pattern ) ;
286
+ conventionBuilder . Add ( b => ( ( RouteEndpointBuilder ) b ) . Order = int . MaxValue ) ;
287
+ return conventionBuilder ;
288
+ }
208
289
}
209
290
}
0 commit comments