Nullable followup for Routing (#23474)

* Nullable followup for routing.

* Update nullability based on usage
* Use nullable enable in a few files

* More nullable
This commit is contained in:
Pranav K 2020-07-06 20:24:20 -07:00 committed by GitHub
parent fd1f1c3559
commit 8750cd1038
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 267 additions and 211 deletions

View File

@ -512,7 +512,7 @@ namespace Microsoft.AspNetCore.Routing
return TryGetValueSlow(key, out value); return TryGetValueSlow(key, out value);
} }
private bool TryGetValueSlow(string key, [NotNullWhen(true)] out object? value) private bool TryGetValueSlow(string key, out object? value)
{ {
if (_propertyStorage != null) if (_propertyStorage != null)
{ {

View File

@ -5,14 +5,14 @@ namespace Microsoft.AspNetCore.Routing
{ {
public partial interface IOutboundParameterTransformer : Microsoft.AspNetCore.Routing.IParameterPolicy public partial interface IOutboundParameterTransformer : Microsoft.AspNetCore.Routing.IParameterPolicy
{ {
string TransformOutbound(object value); string? TransformOutbound(object? value);
} }
public partial interface IParameterPolicy public partial interface IParameterPolicy
{ {
} }
public partial interface IRouteConstraint : Microsoft.AspNetCore.Routing.IParameterPolicy public partial interface IRouteConstraint : Microsoft.AspNetCore.Routing.IParameterPolicy
{ {
bool Match(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.IRouter route, string routeKey, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteDirection routeDirection); bool Match(Microsoft.AspNetCore.Http.HttpContext? httpContext, Microsoft.AspNetCore.Routing.IRouter route, string routeKey, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteDirection routeDirection);
} }
public partial interface IRouteHandler public partial interface IRouteHandler
{ {
@ -20,20 +20,20 @@ namespace Microsoft.AspNetCore.Routing
} }
public partial interface IRouter public partial interface IRouter
{ {
Microsoft.AspNetCore.Routing.VirtualPathData GetVirtualPath(Microsoft.AspNetCore.Routing.VirtualPathContext context); Microsoft.AspNetCore.Routing.VirtualPathData? GetVirtualPath(Microsoft.AspNetCore.Routing.VirtualPathContext context);
System.Threading.Tasks.Task RouteAsync(Microsoft.AspNetCore.Routing.RouteContext context); System.Threading.Tasks.Task RouteAsync(Microsoft.AspNetCore.Routing.RouteContext context);
} }
public partial interface IRoutingFeature public partial interface IRoutingFeature
{ {
Microsoft.AspNetCore.Routing.RouteData RouteData { get; set; } Microsoft.AspNetCore.Routing.RouteData? RouteData { get; set; }
} }
public abstract partial class LinkGenerator public abstract partial class LinkGenerator
{ {
protected LinkGenerator() { } protected LinkGenerator() { }
public abstract string GetPathByAddress<TAddress>(Microsoft.AspNetCore.Http.HttpContext httpContext, TAddress address, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteValueDictionary? ambientValues = null, Microsoft.AspNetCore.Http.PathString? pathBase = default(Microsoft.AspNetCore.Http.PathString?), Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions? options = null); public abstract string? GetPathByAddress<TAddress>(Microsoft.AspNetCore.Http.HttpContext httpContext, TAddress address, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteValueDictionary? ambientValues = null, Microsoft.AspNetCore.Http.PathString? pathBase = default(Microsoft.AspNetCore.Http.PathString?), Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions? options = null);
public abstract string GetPathByAddress<TAddress>(TAddress address, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Http.PathString pathBase = default(Microsoft.AspNetCore.Http.PathString), Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions? options = null); public abstract string? GetPathByAddress<TAddress>(TAddress address, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Http.PathString pathBase = default(Microsoft.AspNetCore.Http.PathString), Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions? options = null);
public abstract string GetUriByAddress<TAddress>(Microsoft.AspNetCore.Http.HttpContext httpContext, TAddress address, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteValueDictionary? ambientValues = null, string? scheme = null, Microsoft.AspNetCore.Http.HostString? host = default(Microsoft.AspNetCore.Http.HostString?), Microsoft.AspNetCore.Http.PathString? pathBase = default(Microsoft.AspNetCore.Http.PathString?), Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions? options = null); public abstract string? GetUriByAddress<TAddress>(Microsoft.AspNetCore.Http.HttpContext httpContext, TAddress address, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteValueDictionary? ambientValues = null, string? scheme = null, Microsoft.AspNetCore.Http.HostString? host = default(Microsoft.AspNetCore.Http.HostString?), Microsoft.AspNetCore.Http.PathString? pathBase = default(Microsoft.AspNetCore.Http.PathString?), Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions? options = null);
public abstract string GetUriByAddress<TAddress>(TAddress address, Microsoft.AspNetCore.Routing.RouteValueDictionary values, string scheme, Microsoft.AspNetCore.Http.HostString host, Microsoft.AspNetCore.Http.PathString pathBase = default(Microsoft.AspNetCore.Http.PathString), Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions? options = null); public abstract string? GetUriByAddress<TAddress>(TAddress address, Microsoft.AspNetCore.Routing.RouteValueDictionary values, string scheme, Microsoft.AspNetCore.Http.HostString host, Microsoft.AspNetCore.Http.PathString pathBase = default(Microsoft.AspNetCore.Http.PathString), Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions? options = null);
} }
public partial class LinkOptions public partial class LinkOptions
{ {
@ -57,13 +57,13 @@ namespace Microsoft.AspNetCore.Routing
public Microsoft.AspNetCore.Routing.RouteValueDictionary DataTokens { get { throw null; } } public Microsoft.AspNetCore.Routing.RouteValueDictionary DataTokens { get { throw null; } }
public System.Collections.Generic.IList<Microsoft.AspNetCore.Routing.IRouter> Routers { get { throw null; } } public System.Collections.Generic.IList<Microsoft.AspNetCore.Routing.IRouter> Routers { get { throw null; } }
public Microsoft.AspNetCore.Routing.RouteValueDictionary Values { get { throw null; } } public Microsoft.AspNetCore.Routing.RouteValueDictionary Values { get { throw null; } }
public Microsoft.AspNetCore.Routing.RouteData.RouteDataSnapshot PushState(Microsoft.AspNetCore.Routing.IRouter router, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteValueDictionary dataTokens) { throw null; } public Microsoft.AspNetCore.Routing.RouteData.RouteDataSnapshot PushState(Microsoft.AspNetCore.Routing.IRouter? router, Microsoft.AspNetCore.Routing.RouteValueDictionary? values, Microsoft.AspNetCore.Routing.RouteValueDictionary? dataTokens) { throw null; }
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public readonly partial struct RouteDataSnapshot public readonly partial struct RouteDataSnapshot
{ {
private readonly object _dummy; private readonly object _dummy;
private readonly int _dummyPrimitive; private readonly int _dummyPrimitive;
public RouteDataSnapshot(Microsoft.AspNetCore.Routing.RouteData routeData, Microsoft.AspNetCore.Routing.RouteValueDictionary dataTokens, System.Collections.Generic.IList<Microsoft.AspNetCore.Routing.IRouter> routers, Microsoft.AspNetCore.Routing.RouteValueDictionary values) { throw null; } public RouteDataSnapshot(Microsoft.AspNetCore.Routing.RouteData routeData, Microsoft.AspNetCore.Routing.RouteValueDictionary? dataTokens, System.Collections.Generic.IList<Microsoft.AspNetCore.Routing.IRouter>? routers, Microsoft.AspNetCore.Routing.RouteValueDictionary? values) { throw null; }
public void Restore() { } public void Restore() { }
} }
} }

View File

@ -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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.AspNetCore.Routing namespace Microsoft.AspNetCore.Routing
@ -14,6 +14,6 @@ namespace Microsoft.AspNetCore.Routing
/// </summary> /// </summary>
/// <param name="value">The route value to transform.</param> /// <param name="value">The route value to transform.</param>
/// <returns>The transformed value.</returns> /// <returns>The transformed value.</returns>
string TransformOutbound(object value); string? TransformOutbound(object? value);
} }
} }

View File

@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Routing
/// </param> /// </param>
/// <returns><c>true</c> if the URL parameter contains a valid value; otherwise, <c>false</c>.</returns> /// <returns><c>true</c> if the URL parameter contains a valid value; otherwise, <c>false</c>.</returns>
bool Match( bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,

View File

@ -9,6 +9,6 @@ namespace Microsoft.AspNetCore.Routing
{ {
Task RouteAsync(RouteContext context); Task RouteAsync(RouteContext context);
VirtualPathData GetVirtualPath(VirtualPathContext context); VirtualPathData? GetVirtualPath(VirtualPathContext context);
} }
} }

View File

@ -1,6 +1,8 @@
// 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
namespace Microsoft.AspNetCore.Routing namespace Microsoft.AspNetCore.Routing
{ {
/// <summary> /// <summary>
@ -11,6 +13,6 @@ namespace Microsoft.AspNetCore.Routing
/// <summary> /// <summary>
/// Gets or sets the <see cref="Routing.RouteData"/> associated with the current request. /// Gets or sets the <see cref="Routing.RouteData"/> associated with the current request.
/// </summary> /// </summary>
RouteData RouteData { get; set; } RouteData? RouteData { get; set; }
} }
} }

View File

@ -11,13 +11,13 @@ namespace Microsoft.AspNetCore.Routing
/// <remarks> /// <remarks>
/// <para> /// <para>
/// Generating URIs in endpoint routing occurs in two phases. First, an address is bound to a list of /// Generating URIs in endpoint routing occurs in two phases. First, an address is bound to a list of
/// endpoints that match the address. Secondly, each endpoint's <c>RoutePattern</c> is evaluated, until /// endpoints that match the address. Secondly, each endpoint's <c>RoutePattern</c> is evaluated, until
/// a route pattern that matches the supplied values is found. The resulting output is combined with /// a route pattern that matches the supplied values is found. The resulting output is combined with
/// the other URI parts supplied to the link generator and returned. /// the other URI parts supplied to the link generator and returned.
/// </para> /// </para>
/// <para> /// <para>
/// The methods provided by the <see cref="LinkGenerator"/> type are general infrastructure, and support /// The methods provided by the <see cref="LinkGenerator"/> type are general infrastructure, and support
/// the standard link generator functionality for any type of address. The most convenient way to use /// the standard link generator functionality for any type of address. The most convenient way to use
/// <see cref="LinkGenerator"/> is through extension methods that perform operations for a specific /// <see cref="LinkGenerator"/> is through extension methods that perform operations for a specific
/// address type. /// address type.
/// </para> /// </para>
@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.Routing
/// <typeparam name="TAddress">The address type.</typeparam> /// <typeparam name="TAddress">The address type.</typeparam>
/// <param name="httpContext">The <see cref="HttpContext"/> associated with the current request.</param> /// <param name="httpContext">The <see cref="HttpContext"/> associated with the current request.</param>
/// <param name="address">The address value. Used to resolve endpoints.</param> /// <param name="address">The address value. Used to resolve endpoints.</param>
/// <param name="values">The route values. Used to expand parameters in the route template. Optional.</param> /// <param name="values">The route values. Used to expand parameters in the route template.</param>
/// <param name="ambientValues">The values associated with the current request. Optional.</param> /// <param name="ambientValues">The values associated with the current request. Optional.</param>
/// <param name="pathBase"> /// <param name="pathBase">
/// An optional URI path base. Prepended to the path in the resulting URI. If not provided, the value of <see cref="HttpRequest.PathBase"/> will be used. /// An optional URI path base. Prepended to the path in the resulting URI. If not provided, the value of <see cref="HttpRequest.PathBase"/> will be used.
@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Routing
/// names from <c>RouteOptions</c>. /// names from <c>RouteOptions</c>.
/// </param> /// </param>
/// <returns>A URI with an absolute path, or <c>null</c>.</returns> /// <returns>A URI with an absolute path, or <c>null</c>.</returns>
public abstract string GetPathByAddress<TAddress>( public abstract string? GetPathByAddress<TAddress>(
HttpContext httpContext, HttpContext httpContext,
TAddress address, TAddress address,
RouteValueDictionary values, RouteValueDictionary values,
@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Routing
/// </summary> /// </summary>
/// <typeparam name="TAddress">The address type.</typeparam> /// <typeparam name="TAddress">The address type.</typeparam>
/// <param name="address">The address value. Used to resolve endpoints.</param> /// <param name="address">The address value. Used to resolve endpoints.</param>
/// <param name="values">The route values. Used to expand parameters in the route template. Optional.</param> /// <param name="values">The route values. Used to expand parameters in the route template.</param>
/// <param name="pathBase">An optional URI path base. Prepended to the path in the resulting URI.</param> /// <param name="pathBase">An optional URI path base. Prepended to the path in the resulting URI.</param>
/// <param name="fragment">An optional URI fragment. Appended to the resulting URI.</param> /// <param name="fragment">An optional URI fragment. Appended to the resulting URI.</param>
/// <param name="options"> /// <param name="options">
@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Routing
/// names from <c>RouteOptions</c>. /// names from <c>RouteOptions</c>.
/// </param> /// </param>
/// <returns>A URI with an absolute path, or <c>null</c>.</returns> /// <returns>A URI with an absolute path, or <c>null</c>.</returns>
public abstract string GetPathByAddress<TAddress>( public abstract string? GetPathByAddress<TAddress>(
TAddress address, TAddress address,
RouteValueDictionary values, RouteValueDictionary values,
PathString pathBase = default, PathString pathBase = default,
@ -76,7 +76,7 @@ namespace Microsoft.AspNetCore.Routing
/// <typeparam name="TAddress">The address type.</typeparam> /// <typeparam name="TAddress">The address type.</typeparam>
/// <param name="httpContext">The <see cref="HttpContext"/> associated with the current request.</param> /// <param name="httpContext">The <see cref="HttpContext"/> associated with the current request.</param>
/// <param name="address">The address value. Used to resolve endpoints.</param> /// <param name="address">The address value. Used to resolve endpoints.</param>
/// <param name="values">The route values. Used to expand parameters in the route template. Optional.</param> /// <param name="values">The route values. Used to expand parameters in the route template.</param>
/// <param name="ambientValues">The values associated with the current request. Optional.</param> /// <param name="ambientValues">The values associated with the current request. Optional.</param>
/// <param name="scheme"> /// <param name="scheme">
/// The URI scheme, applied to the resulting URI. Optional. If not provided, the value of <see cref="HttpRequest.Scheme"/> will be used. /// The URI scheme, applied to the resulting URI. Optional. If not provided, the value of <see cref="HttpRequest.Scheme"/> will be used.
@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.Routing
/// your deployment environment. /// your deployment environment.
/// </para> /// </para>
/// </remarks> /// </remarks>
public abstract string GetUriByAddress<TAddress>( public abstract string? GetUriByAddress<TAddress>(
HttpContext httpContext, HttpContext httpContext,
TAddress address, TAddress address,
RouteValueDictionary values, RouteValueDictionary values,
@ -118,7 +118,7 @@ namespace Microsoft.AspNetCore.Routing
/// </summary> /// </summary>
/// <typeparam name="TAddress">The address type.</typeparam> /// <typeparam name="TAddress">The address type.</typeparam>
/// <param name="address">The address value. Used to resolve endpoints.</param> /// <param name="address">The address value. Used to resolve endpoints.</param>
/// <param name="values">The route values. Used to expand parameters in the route template. Optional.</param> /// <param name="values">The route values. Used to expand parameters in the route template.</param>
/// <param name="scheme">The URI scheme, applied to the resulting URI.</param> /// <param name="scheme">The URI scheme, applied to the resulting URI.</param>
/// <param name="host"> /// <param name="host">
/// The URI host/authority, applied to the resulting URI. /// The URI host/authority, applied to the resulting URI.
@ -139,7 +139,7 @@ namespace Microsoft.AspNetCore.Routing
/// your deployment environment. /// your deployment environment.
/// </para> /// </para>
/// </remarks> /// </remarks>
public abstract string GetUriByAddress<TAddress>( public abstract string? GetUriByAddress<TAddress>(
TAddress address, TAddress address,
RouteValueDictionary values, RouteValueDictionary values,
string scheme, string scheme,

View File

@ -1,8 +1,11 @@
// 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
namespace Microsoft.AspNetCore.Routing namespace Microsoft.AspNetCore.Routing
{ {
@ -11,9 +14,9 @@ namespace Microsoft.AspNetCore.Routing
/// </summary> /// </summary>
public class RouteData public class RouteData
{ {
private RouteValueDictionary _dataTokens; private RouteValueDictionary? _dataTokens;
private List<IRouter> _routers; private List<IRouter>? _routers;
private RouteValueDictionary _values; private RouteValueDictionary? _values;
/// <summary> /// <summary>
/// Creates a new instance of <see cref="RouteData"/> instance. /// Creates a new instance of <see cref="RouteData"/> instance.
@ -138,14 +141,16 @@ namespace Microsoft.AspNetCore.Routing
/// <see cref="DataTokens"/> will not be changed. /// <see cref="DataTokens"/> will not be changed.
/// </param> /// </param>
/// <returns>A <see cref="RouteDataSnapshot"/> that captures the current state.</returns> /// <returns>A <see cref="RouteDataSnapshot"/> that captures the current state.</returns>
public RouteDataSnapshot PushState(IRouter router, RouteValueDictionary values, RouteValueDictionary dataTokens) public RouteDataSnapshot PushState(IRouter? router, RouteValueDictionary? values, RouteValueDictionary? dataTokens)
{ {
// Perf: this is optimized for small list sizes, in particular to avoid overhead of a native call in // Perf: this is optimized for small list sizes, in particular to avoid overhead of a native call in
// Array.CopyTo inside the List(IEnumerable<T>) constructor. // Array.CopyTo inside the List(IEnumerable<T>) constructor.
List<IRouter> routers = null; List<IRouter>? routers = null;
var count = _routers?.Count; var count = _routers?.Count;
if (count > 0) if (count > 0)
{ {
Debug.Assert(_routers != null);
routers = new List<IRouter>(count.Value); routers = new List<IRouter>(count.Value);
for (var i = 0; i < count.Value; i++) for (var i = 0; i < count.Value; i++)
{ {
@ -192,9 +197,9 @@ namespace Microsoft.AspNetCore.Routing
public readonly struct RouteDataSnapshot public readonly struct RouteDataSnapshot
{ {
private readonly RouteData _routeData; private readonly RouteData _routeData;
private readonly RouteValueDictionary _dataTokens; private readonly RouteValueDictionary? _dataTokens;
private readonly IList<IRouter> _routers; private readonly IList<IRouter>? _routers;
private readonly RouteValueDictionary _values; private readonly RouteValueDictionary? _values;
/// <summary> /// <summary>
/// Creates a new instance of <see cref="RouteDataSnapshot"/> for <paramref name="routeData"/>. /// Creates a new instance of <see cref="RouteDataSnapshot"/> for <paramref name="routeData"/>.
@ -205,9 +210,9 @@ namespace Microsoft.AspNetCore.Routing
/// <param name="values">The route values.</param> /// <param name="values">The route values.</param>
public RouteDataSnapshot( public RouteDataSnapshot(
RouteData routeData, RouteData routeData,
RouteValueDictionary dataTokens, RouteValueDictionary? dataTokens,
IList<IRouter> routers, IList<IRouter>? routers,
RouteValueDictionary values) RouteValueDictionary? values)
{ {
if (routeData == null) if (routeData == null)
{ {
@ -231,11 +236,11 @@ namespace Microsoft.AspNetCore.Routing
} }
else if (_dataTokens == null) else if (_dataTokens == null)
{ {
_routeData._dataTokens.Clear(); _routeData._dataTokens!.Clear();
} }
else else
{ {
_routeData._dataTokens.Clear(); _routeData._dataTokens!.Clear();
foreach (var kvp in _dataTokens) foreach (var kvp in _dataTokens)
{ {
@ -251,7 +256,7 @@ namespace Microsoft.AspNetCore.Routing
{ {
// Perf: this is optimized for small list sizes, in particular to avoid overhead of a native call in // Perf: this is optimized for small list sizes, in particular to avoid overhead of a native call in
// Array.Clear inside the List.Clear() method. // Array.Clear inside the List.Clear() method.
var routers = _routeData._routers; var routers = _routeData._routers!;
for (var i = routers.Count - 1; i >= 0 ; i--) for (var i = routers.Count - 1; i >= 0 ; i--)
{ {
routers.RemoveAt(i); routers.RemoveAt(i);
@ -264,7 +269,7 @@ namespace Microsoft.AspNetCore.Routing
// //
// We want to basically copy the contents of _routers in _routeData._routers - this change does // We want to basically copy the contents of _routers in _routeData._routers - this change does
// that with the minimal number of reads/writes and without calling Clear(). // that with the minimal number of reads/writes and without calling Clear().
var routers = _routeData._routers; var routers = _routeData._routers!;
var snapshotRouters = _routers; var snapshotRouters = _routers;
// This is made more complicated by the fact that List[int] throws if i == Count, so we have // This is made more complicated by the fact that List[int] throws if i == Count, so we have
@ -293,11 +298,11 @@ namespace Microsoft.AspNetCore.Routing
} }
else if (_values == null) else if (_values == null)
{ {
_routeData._values.Clear(); _routeData._values!.Clear();
} }
else else
{ {
_routeData._values.Clear(); _routeData._values!.Clear();
foreach (var kvp in _values) foreach (var kvp in _values)
{ {

View File

@ -1,6 +1,8 @@
// 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System; using System;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http.Features;

View File

@ -26,10 +26,10 @@ namespace Microsoft.AspNetCore.Builder
} }
public static partial class MapRouteRouteBuilderExtensions public static partial class MapRouteRouteBuilderExtensions
{ {
public static Microsoft.AspNetCore.Routing.IRouteBuilder MapRoute(this Microsoft.AspNetCore.Routing.IRouteBuilder routeBuilder, string name, string template) { throw null; } public static Microsoft.AspNetCore.Routing.IRouteBuilder MapRoute(this Microsoft.AspNetCore.Routing.IRouteBuilder routeBuilder, string? name, string? template) { throw null; }
public static Microsoft.AspNetCore.Routing.IRouteBuilder MapRoute(this Microsoft.AspNetCore.Routing.IRouteBuilder routeBuilder, string name, string template, object defaults) { throw null; } public static Microsoft.AspNetCore.Routing.IRouteBuilder MapRoute(this Microsoft.AspNetCore.Routing.IRouteBuilder routeBuilder, string? name, string? template, object? defaults) { throw null; }
public static Microsoft.AspNetCore.Routing.IRouteBuilder MapRoute(this Microsoft.AspNetCore.Routing.IRouteBuilder routeBuilder, string name, string template, object defaults, object constraints) { throw null; } public static Microsoft.AspNetCore.Routing.IRouteBuilder MapRoute(this Microsoft.AspNetCore.Routing.IRouteBuilder routeBuilder, string? name, string? template, object? defaults, object? constraints) { throw null; }
public static Microsoft.AspNetCore.Routing.IRouteBuilder MapRoute(this Microsoft.AspNetCore.Routing.IRouteBuilder routeBuilder, string name, string template, object defaults, object constraints, object dataTokens) { throw null; } public static Microsoft.AspNetCore.Routing.IRouteBuilder MapRoute(this Microsoft.AspNetCore.Routing.IRouteBuilder routeBuilder, string? name, string? template, object? defaults, object? constraints, object? dataTokens) { throw null; }
} }
public partial class RouterMiddleware public partial class RouterMiddleware
{ {
@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.Routing
public partial class DefaultInlineConstraintResolver : Microsoft.AspNetCore.Routing.IInlineConstraintResolver public partial class DefaultInlineConstraintResolver : Microsoft.AspNetCore.Routing.IInlineConstraintResolver
{ {
public DefaultInlineConstraintResolver(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Routing.RouteOptions> routeOptions, System.IServiceProvider serviceProvider) { } public DefaultInlineConstraintResolver(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Routing.RouteOptions> routeOptions, System.IServiceProvider serviceProvider) { }
public virtual Microsoft.AspNetCore.Routing.IRouteConstraint ResolveConstraint(string inlineConstraint) { throw null; } public virtual Microsoft.AspNetCore.Routing.IRouteConstraint? ResolveConstraint(string inlineConstraint) { throw null; }
} }
public abstract partial class EndpointDataSource public abstract partial class EndpointDataSource
{ {
@ -137,11 +137,11 @@ namespace Microsoft.AspNetCore.Routing
} }
public partial interface IInlineConstraintResolver public partial interface IInlineConstraintResolver
{ {
Microsoft.AspNetCore.Routing.IRouteConstraint ResolveConstraint(string inlineConstraint); Microsoft.AspNetCore.Routing.IRouteConstraint? ResolveConstraint(string inlineConstraint);
} }
public partial interface INamedRouter : Microsoft.AspNetCore.Routing.IRouter public partial interface INamedRouter : Microsoft.AspNetCore.Routing.IRouter
{ {
string Name { get; } string? Name { get; }
} }
public static partial class InlineRouteParameterParser public static partial class InlineRouteParameterParser
{ {
@ -150,7 +150,7 @@ namespace Microsoft.AspNetCore.Routing
public partial interface IRouteBuilder public partial interface IRouteBuilder
{ {
Microsoft.AspNetCore.Builder.IApplicationBuilder ApplicationBuilder { get; } Microsoft.AspNetCore.Builder.IApplicationBuilder ApplicationBuilder { get; }
Microsoft.AspNetCore.Routing.IRouter DefaultHandler { get; set; } Microsoft.AspNetCore.Routing.IRouter? DefaultHandler { get; set; }
System.Collections.Generic.IList<Microsoft.AspNetCore.Routing.IRouter> Routes { get; } System.Collections.Generic.IList<Microsoft.AspNetCore.Routing.IRouter> Routes { get; }
System.IServiceProvider ServiceProvider { get; } System.IServiceProvider ServiceProvider { get; }
Microsoft.AspNetCore.Routing.IRouter Build(); Microsoft.AspNetCore.Routing.IRouter Build();
@ -205,7 +205,7 @@ namespace Microsoft.AspNetCore.Routing
protected ParameterPolicyFactory() { } protected ParameterPolicyFactory() { }
public abstract Microsoft.AspNetCore.Routing.IParameterPolicy Create(Microsoft.AspNetCore.Routing.Patterns.RoutePatternParameterPart parameter, Microsoft.AspNetCore.Routing.IParameterPolicy parameterPolicy); public abstract Microsoft.AspNetCore.Routing.IParameterPolicy Create(Microsoft.AspNetCore.Routing.Patterns.RoutePatternParameterPart parameter, Microsoft.AspNetCore.Routing.IParameterPolicy parameterPolicy);
public Microsoft.AspNetCore.Routing.IParameterPolicy Create(Microsoft.AspNetCore.Routing.Patterns.RoutePatternParameterPart parameter, Microsoft.AspNetCore.Routing.Patterns.RoutePatternParameterPolicyReference reference) { throw null; } public Microsoft.AspNetCore.Routing.IParameterPolicy Create(Microsoft.AspNetCore.Routing.Patterns.RoutePatternParameterPart parameter, Microsoft.AspNetCore.Routing.Patterns.RoutePatternParameterPolicyReference reference) { throw null; }
public abstract Microsoft.AspNetCore.Routing.IParameterPolicy Create(Microsoft.AspNetCore.Routing.Patterns.RoutePatternParameterPart parameter, string inlineText); public abstract Microsoft.AspNetCore.Routing.IParameterPolicy Create(Microsoft.AspNetCore.Routing.Patterns.RoutePatternParameterPart? parameter, string inlineText);
} }
public static partial class RequestDelegateRouteBuilderExtensions public static partial class RequestDelegateRouteBuilderExtensions
{ {
@ -230,35 +230,35 @@ namespace Microsoft.AspNetCore.Routing
public partial class Route : Microsoft.AspNetCore.Routing.RouteBase public partial class Route : Microsoft.AspNetCore.Routing.RouteBase
{ {
public Route(Microsoft.AspNetCore.Routing.IRouter target, string routeTemplate, Microsoft.AspNetCore.Routing.IInlineConstraintResolver inlineConstraintResolver) : base (default(string), default(string), default(Microsoft.AspNetCore.Routing.IInlineConstraintResolver), default(Microsoft.AspNetCore.Routing.RouteValueDictionary), default(System.Collections.Generic.IDictionary<string, object>), default(Microsoft.AspNetCore.Routing.RouteValueDictionary)) { } public Route(Microsoft.AspNetCore.Routing.IRouter target, string routeTemplate, Microsoft.AspNetCore.Routing.IInlineConstraintResolver inlineConstraintResolver) : base (default(string), default(string), default(Microsoft.AspNetCore.Routing.IInlineConstraintResolver), default(Microsoft.AspNetCore.Routing.RouteValueDictionary), default(System.Collections.Generic.IDictionary<string, object>), default(Microsoft.AspNetCore.Routing.RouteValueDictionary)) { }
public Route(Microsoft.AspNetCore.Routing.IRouter target, string routeTemplate, Microsoft.AspNetCore.Routing.RouteValueDictionary defaults, System.Collections.Generic.IDictionary<string, object> constraints, Microsoft.AspNetCore.Routing.RouteValueDictionary dataTokens, Microsoft.AspNetCore.Routing.IInlineConstraintResolver inlineConstraintResolver) : base (default(string), default(string), default(Microsoft.AspNetCore.Routing.IInlineConstraintResolver), default(Microsoft.AspNetCore.Routing.RouteValueDictionary), default(System.Collections.Generic.IDictionary<string, object>), default(Microsoft.AspNetCore.Routing.RouteValueDictionary)) { } public Route(Microsoft.AspNetCore.Routing.IRouter target, string routeTemplate, Microsoft.AspNetCore.Routing.RouteValueDictionary? defaults, System.Collections.Generic.IDictionary<string, object>? constraints, Microsoft.AspNetCore.Routing.RouteValueDictionary? dataTokens, Microsoft.AspNetCore.Routing.IInlineConstraintResolver inlineConstraintResolver) : base (default(string), default(string), default(Microsoft.AspNetCore.Routing.IInlineConstraintResolver), default(Microsoft.AspNetCore.Routing.RouteValueDictionary), default(System.Collections.Generic.IDictionary<string, object>), default(Microsoft.AspNetCore.Routing.RouteValueDictionary)) { }
public Route(Microsoft.AspNetCore.Routing.IRouter target, string routeName, string routeTemplate, Microsoft.AspNetCore.Routing.RouteValueDictionary defaults, System.Collections.Generic.IDictionary<string, object> constraints, Microsoft.AspNetCore.Routing.RouteValueDictionary dataTokens, Microsoft.AspNetCore.Routing.IInlineConstraintResolver inlineConstraintResolver) : base (default(string), default(string), default(Microsoft.AspNetCore.Routing.IInlineConstraintResolver), default(Microsoft.AspNetCore.Routing.RouteValueDictionary), default(System.Collections.Generic.IDictionary<string, object>), default(Microsoft.AspNetCore.Routing.RouteValueDictionary)) { } public Route(Microsoft.AspNetCore.Routing.IRouter target, string? routeName, string? routeTemplate, Microsoft.AspNetCore.Routing.RouteValueDictionary? defaults, System.Collections.Generic.IDictionary<string, object>? constraints, Microsoft.AspNetCore.Routing.RouteValueDictionary? dataTokens, Microsoft.AspNetCore.Routing.IInlineConstraintResolver inlineConstraintResolver) : base (default(string), default(string), default(Microsoft.AspNetCore.Routing.IInlineConstraintResolver), default(Microsoft.AspNetCore.Routing.RouteValueDictionary), default(System.Collections.Generic.IDictionary<string, object>), default(Microsoft.AspNetCore.Routing.RouteValueDictionary)) { }
public string RouteTemplate { get { throw null; } } public string RouteTemplate { get { throw null; } }
protected override System.Threading.Tasks.Task OnRouteMatched(Microsoft.AspNetCore.Routing.RouteContext context) { throw null; } protected override System.Threading.Tasks.Task OnRouteMatched(Microsoft.AspNetCore.Routing.RouteContext context) { throw null; }
protected override Microsoft.AspNetCore.Routing.VirtualPathData OnVirtualPathGenerated(Microsoft.AspNetCore.Routing.VirtualPathContext context) { throw null; } protected override Microsoft.AspNetCore.Routing.VirtualPathData? OnVirtualPathGenerated(Microsoft.AspNetCore.Routing.VirtualPathContext context) { throw null; }
} }
public abstract partial class RouteBase : Microsoft.AspNetCore.Routing.INamedRouter, Microsoft.AspNetCore.Routing.IRouter public abstract partial class RouteBase : Microsoft.AspNetCore.Routing.INamedRouter, Microsoft.AspNetCore.Routing.IRouter
{ {
public RouteBase(string template, string name, Microsoft.AspNetCore.Routing.IInlineConstraintResolver constraintResolver, Microsoft.AspNetCore.Routing.RouteValueDictionary defaults, System.Collections.Generic.IDictionary<string, object> constraints, Microsoft.AspNetCore.Routing.RouteValueDictionary dataTokens) { } public RouteBase(string? template, string? name, Microsoft.AspNetCore.Routing.IInlineConstraintResolver constraintResolver, Microsoft.AspNetCore.Routing.RouteValueDictionary? defaults, System.Collections.Generic.IDictionary<string, object>? constraints, Microsoft.AspNetCore.Routing.RouteValueDictionary? dataTokens) { }
protected virtual Microsoft.AspNetCore.Routing.IInlineConstraintResolver ConstraintResolver { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } protected virtual Microsoft.AspNetCore.Routing.IInlineConstraintResolver ConstraintResolver { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public virtual System.Collections.Generic.IDictionary<string, Microsoft.AspNetCore.Routing.IRouteConstraint> Constraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } public virtual System.Collections.Generic.IDictionary<string, Microsoft.AspNetCore.Routing.IRouteConstraint> Constraints { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } }
public virtual Microsoft.AspNetCore.Routing.RouteValueDictionary DataTokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } public virtual Microsoft.AspNetCore.Routing.RouteValueDictionary DataTokens { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } }
public virtual Microsoft.AspNetCore.Routing.RouteValueDictionary Defaults { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } public virtual Microsoft.AspNetCore.Routing.RouteValueDictionary Defaults { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } }
public virtual string Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } public virtual string? Name { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } }
public virtual Microsoft.AspNetCore.Routing.Template.RouteTemplate ParsedTemplate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } } public virtual Microsoft.AspNetCore.Routing.Template.RouteTemplate ParsedTemplate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] protected set { } }
protected static System.Collections.Generic.IDictionary<string, Microsoft.AspNetCore.Routing.IRouteConstraint> GetConstraints(Microsoft.AspNetCore.Routing.IInlineConstraintResolver inlineConstraintResolver, Microsoft.AspNetCore.Routing.Template.RouteTemplate parsedTemplate, System.Collections.Generic.IDictionary<string, object> constraints) { throw null; } protected static System.Collections.Generic.IDictionary<string, Microsoft.AspNetCore.Routing.IRouteConstraint> GetConstraints(Microsoft.AspNetCore.Routing.IInlineConstraintResolver inlineConstraintResolver, Microsoft.AspNetCore.Routing.Template.RouteTemplate parsedTemplate, System.Collections.Generic.IDictionary<string, object>? constraints) { throw null; }
protected static Microsoft.AspNetCore.Routing.RouteValueDictionary GetDefaults(Microsoft.AspNetCore.Routing.Template.RouteTemplate parsedTemplate, Microsoft.AspNetCore.Routing.RouteValueDictionary defaults) { throw null; } protected static Microsoft.AspNetCore.Routing.RouteValueDictionary GetDefaults(Microsoft.AspNetCore.Routing.Template.RouteTemplate parsedTemplate, Microsoft.AspNetCore.Routing.RouteValueDictionary? defaults) { throw null; }
public virtual Microsoft.AspNetCore.Routing.VirtualPathData GetVirtualPath(Microsoft.AspNetCore.Routing.VirtualPathContext context) { throw null; } public virtual Microsoft.AspNetCore.Routing.VirtualPathData? GetVirtualPath(Microsoft.AspNetCore.Routing.VirtualPathContext context) { throw null; }
protected abstract System.Threading.Tasks.Task OnRouteMatched(Microsoft.AspNetCore.Routing.RouteContext context); protected abstract System.Threading.Tasks.Task OnRouteMatched(Microsoft.AspNetCore.Routing.RouteContext context);
protected abstract Microsoft.AspNetCore.Routing.VirtualPathData OnVirtualPathGenerated(Microsoft.AspNetCore.Routing.VirtualPathContext context); protected abstract Microsoft.AspNetCore.Routing.VirtualPathData? OnVirtualPathGenerated(Microsoft.AspNetCore.Routing.VirtualPathContext context);
public virtual System.Threading.Tasks.Task RouteAsync(Microsoft.AspNetCore.Routing.RouteContext context) { throw null; } public virtual System.Threading.Tasks.Task RouteAsync(Microsoft.AspNetCore.Routing.RouteContext context) { throw null; }
public override string ToString() { throw null; } public override string ToString() { throw null; }
} }
public partial class RouteBuilder : Microsoft.AspNetCore.Routing.IRouteBuilder public partial class RouteBuilder : Microsoft.AspNetCore.Routing.IRouteBuilder
{ {
public RouteBuilder(Microsoft.AspNetCore.Builder.IApplicationBuilder applicationBuilder) { } public RouteBuilder(Microsoft.AspNetCore.Builder.IApplicationBuilder applicationBuilder) { }
public RouteBuilder(Microsoft.AspNetCore.Builder.IApplicationBuilder applicationBuilder, Microsoft.AspNetCore.Routing.IRouter defaultHandler) { } public RouteBuilder(Microsoft.AspNetCore.Builder.IApplicationBuilder applicationBuilder, Microsoft.AspNetCore.Routing.IRouter? defaultHandler) { }
public Microsoft.AspNetCore.Builder.IApplicationBuilder ApplicationBuilder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public Microsoft.AspNetCore.Builder.IApplicationBuilder ApplicationBuilder { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public Microsoft.AspNetCore.Routing.IRouter DefaultHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Routing.IRouter? DefaultHandler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public System.Collections.Generic.IList<Microsoft.AspNetCore.Routing.IRouter> Routes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.Collections.Generic.IList<Microsoft.AspNetCore.Routing.IRouter> Routes { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public System.IServiceProvider ServiceProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.IServiceProvider ServiceProvider { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public Microsoft.AspNetCore.Routing.IRouter Build() { throw null; } public Microsoft.AspNetCore.Routing.IRouter Build() { throw null; }
@ -269,7 +269,7 @@ namespace Microsoft.AspNetCore.Routing
public int Count { get { throw null; } } public int Count { get { throw null; } }
public Microsoft.AspNetCore.Routing.IRouter this[int index] { get { throw null; } } public Microsoft.AspNetCore.Routing.IRouter this[int index] { get { throw null; } }
public void Add(Microsoft.AspNetCore.Routing.IRouter router) { } public void Add(Microsoft.AspNetCore.Routing.IRouter router) { }
public virtual Microsoft.AspNetCore.Routing.VirtualPathData GetVirtualPath(Microsoft.AspNetCore.Routing.VirtualPathContext context) { throw null; } public virtual Microsoft.AspNetCore.Routing.VirtualPathData? GetVirtualPath(Microsoft.AspNetCore.Routing.VirtualPathContext context) { throw null; }
[System.Diagnostics.DebuggerStepThroughAttribute] [System.Diagnostics.DebuggerStepThroughAttribute]
public virtual System.Threading.Tasks.Task RouteAsync(Microsoft.AspNetCore.Routing.RouteContext context) { throw null; } public virtual System.Threading.Tasks.Task RouteAsync(Microsoft.AspNetCore.Routing.RouteContext context) { throw null; }
} }
@ -307,7 +307,7 @@ namespace Microsoft.AspNetCore.Routing
{ {
public RouteHandler(Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { } public RouteHandler(Microsoft.AspNetCore.Http.RequestDelegate requestDelegate) { }
public Microsoft.AspNetCore.Http.RequestDelegate GetRequestHandler(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.RouteData routeData) { throw null; } public Microsoft.AspNetCore.Http.RequestDelegate GetRequestHandler(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.RouteData routeData) { throw null; }
public Microsoft.AspNetCore.Routing.VirtualPathData GetVirtualPath(Microsoft.AspNetCore.Routing.VirtualPathContext context) { throw null; } public Microsoft.AspNetCore.Routing.VirtualPathData? GetVirtualPath(Microsoft.AspNetCore.Routing.VirtualPathContext context) { throw null; }
public System.Threading.Tasks.Task RouteAsync(Microsoft.AspNetCore.Routing.RouteContext context) { throw null; } public System.Threading.Tasks.Task RouteAsync(Microsoft.AspNetCore.Routing.RouteContext context) { throw null; }
} }
[System.Diagnostics.DebuggerDisplayAttribute("{DebuggerToString(),nq}")] [System.Diagnostics.DebuggerDisplayAttribute("{DebuggerToString(),nq}")]
@ -335,14 +335,14 @@ namespace Microsoft.AspNetCore.Routing
public partial class RouteValuesAddress public partial class RouteValuesAddress
{ {
public RouteValuesAddress() { } public RouteValuesAddress() { }
public Microsoft.AspNetCore.Routing.RouteValueDictionary AmbientValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Routing.RouteValueDictionary? AmbientValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public Microsoft.AspNetCore.Routing.RouteValueDictionary ExplicitValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Routing.RouteValueDictionary ExplicitValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public string? RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
} }
public partial class RoutingFeature : Microsoft.AspNetCore.Routing.IRoutingFeature public partial class RoutingFeature : Microsoft.AspNetCore.Routing.IRoutingFeature
{ {
public RoutingFeature() { } public RoutingFeature() { }
public Microsoft.AspNetCore.Routing.RouteData RouteData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } } public Microsoft.AspNetCore.Routing.RouteData? RouteData { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
} }
public sealed partial class SuppressLinkGenerationMetadata : Microsoft.AspNetCore.Routing.ISuppressLinkGenerationMetadata public sealed partial class SuppressLinkGenerationMetadata : Microsoft.AspNetCore.Routing.ISuppressLinkGenerationMetadata
{ {
@ -522,15 +522,15 @@ namespace Microsoft.AspNetCore.Routing.Matching
public sealed partial class EndpointMetadataComparer : System.Collections.Generic.IComparer<Microsoft.AspNetCore.Http.Endpoint> public sealed partial class EndpointMetadataComparer : System.Collections.Generic.IComparer<Microsoft.AspNetCore.Http.Endpoint>
{ {
internal EndpointMetadataComparer() { } internal EndpointMetadataComparer() { }
int System.Collections.Generic.IComparer<Microsoft.AspNetCore.Http.Endpoint>.Compare(Microsoft.AspNetCore.Http.Endpoint x, Microsoft.AspNetCore.Http.Endpoint y) { throw null; } int System.Collections.Generic.IComparer<Microsoft.AspNetCore.Http.Endpoint>.Compare(Microsoft.AspNetCore.Http.Endpoint? x, Microsoft.AspNetCore.Http.Endpoint? y) { throw null; }
} }
public abstract partial class EndpointMetadataComparer<TMetadata> : System.Collections.Generic.IComparer<Microsoft.AspNetCore.Http.Endpoint> where TMetadata : class public abstract partial class EndpointMetadataComparer<TMetadata> : System.Collections.Generic.IComparer<Microsoft.AspNetCore.Http.Endpoint> where TMetadata : class
{ {
public static readonly Microsoft.AspNetCore.Routing.Matching.EndpointMetadataComparer<TMetadata> Default; public static readonly Microsoft.AspNetCore.Routing.Matching.EndpointMetadataComparer<TMetadata> Default;
protected EndpointMetadataComparer() { } protected EndpointMetadataComparer() { }
public int Compare(Microsoft.AspNetCore.Http.Endpoint x, Microsoft.AspNetCore.Http.Endpoint y) { throw null; } public int Compare(Microsoft.AspNetCore.Http.Endpoint? x, Microsoft.AspNetCore.Http.Endpoint? y) { throw null; }
protected virtual int CompareMetadata(TMetadata x, TMetadata y) { throw null; } protected virtual int CompareMetadata(TMetadata? x, TMetadata? y) { throw null; }
protected virtual TMetadata GetMetadata(Microsoft.AspNetCore.Http.Endpoint endpoint) { throw null; } protected virtual TMetadata? GetMetadata(Microsoft.AspNetCore.Http.Endpoint endpoint) { throw null; }
} }
public abstract partial class EndpointSelector public abstract partial class EndpointSelector
{ {
@ -734,17 +734,17 @@ namespace Microsoft.AspNetCore.Routing.Template
public System.Collections.Generic.IList<Microsoft.AspNetCore.Routing.Template.TemplatePart> Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.Collections.Generic.IList<Microsoft.AspNetCore.Routing.Template.TemplatePart> Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public System.Collections.Generic.IList<Microsoft.AspNetCore.Routing.Template.TemplateSegment> Segments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.Collections.Generic.IList<Microsoft.AspNetCore.Routing.Template.TemplateSegment> Segments { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public string TemplateText { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public string TemplateText { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public Microsoft.AspNetCore.Routing.Template.TemplatePart GetParameter(string name) { throw null; } public Microsoft.AspNetCore.Routing.Template.TemplatePart? GetParameter(string name) { throw null; }
public Microsoft.AspNetCore.Routing.Template.TemplateSegment GetSegment(int index) { throw null; } public Microsoft.AspNetCore.Routing.Template.TemplateSegment? GetSegment(int index) { throw null; }
public Microsoft.AspNetCore.Routing.Patterns.RoutePattern ToRoutePattern() { throw null; } public Microsoft.AspNetCore.Routing.Patterns.RoutePattern ToRoutePattern() { throw null; }
} }
public partial class TemplateBinder public partial class TemplateBinder
{ {
internal TemplateBinder() { } internal TemplateBinder() { }
public string BindValues(Microsoft.AspNetCore.Routing.RouteValueDictionary acceptedValues) { throw null; } public string? BindValues(Microsoft.AspNetCore.Routing.RouteValueDictionary acceptedValues) { throw null; }
public Microsoft.AspNetCore.Routing.Template.TemplateValuesResult GetValues(Microsoft.AspNetCore.Routing.RouteValueDictionary ambientValues, Microsoft.AspNetCore.Routing.RouteValueDictionary values) { throw null; } public Microsoft.AspNetCore.Routing.Template.TemplateValuesResult? GetValues(Microsoft.AspNetCore.Routing.RouteValueDictionary? ambientValues, Microsoft.AspNetCore.Routing.RouteValueDictionary values) { throw null; }
public static bool RoutePartsEqual(object a, object b) { throw null; } public static bool RoutePartsEqual(object? a, object? b) { throw null; }
public bool TryProcessConstraints(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.RouteValueDictionary combinedValues, out string parameterName, out Microsoft.AspNetCore.Routing.IRouteConstraint constraint) { throw null; } public bool TryProcessConstraints(Microsoft.AspNetCore.Http.HttpContext? httpContext, Microsoft.AspNetCore.Routing.RouteValueDictionary combinedValues, out string? parameterName, out Microsoft.AspNetCore.Routing.IRouteConstraint? constraint) { throw null; }
} }
public abstract partial class TemplateBinderFactory public abstract partial class TemplateBinderFactory
{ {

View File

@ -1,6 +1,8 @@
// 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
@ -46,7 +48,7 @@ namespace Microsoft.AspNetCore.Routing
/// The entire string "arg1, arg2, 12" will be treated as a single argument. /// The entire string "arg1, arg2, 12" will be treated as a single argument.
/// In all other cases arguments are split at comma. /// In all other cases arguments are split at comma.
/// </example> /// </example>
public virtual IRouteConstraint ResolveConstraint(string inlineConstraint) public virtual IRouteConstraint? ResolveConstraint(string inlineConstraint)
{ {
if (inlineConstraint == null) if (inlineConstraint == null)
{ {

View File

@ -1,19 +1,19 @@
// 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Routing.Template; using Microsoft.AspNetCore.Routing.Template;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.ObjectPool;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Routing namespace Microsoft.AspNetCore.Routing
@ -68,14 +68,14 @@ namespace Microsoft.AspNetCore.Routing
}; };
} }
public override string GetPathByAddress<TAddress>( public override string? GetPathByAddress<TAddress>(
HttpContext httpContext, HttpContext httpContext,
TAddress address, TAddress address,
RouteValueDictionary values, RouteValueDictionary values,
RouteValueDictionary ambientValues = default, RouteValueDictionary? ambientValues = default,
PathString? pathBase = default, PathString? pathBase = default,
FragmentString fragment = default, FragmentString fragment = default,
LinkOptions options = null) LinkOptions? options = null)
{ {
if (httpContext == null) if (httpContext == null)
{ {
@ -98,12 +98,12 @@ namespace Microsoft.AspNetCore.Routing
options); options);
} }
public override string GetPathByAddress<TAddress>( public override string? GetPathByAddress<TAddress>(
TAddress address, TAddress address,
RouteValueDictionary values, RouteValueDictionary values,
PathString pathBase = default, PathString pathBase = default,
FragmentString fragment = default, FragmentString fragment = default,
LinkOptions options = null) LinkOptions? options = null)
{ {
var endpoints = GetEndpoints(address); var endpoints = GetEndpoints(address);
if (endpoints.Count == 0) if (endpoints.Count == 0)
@ -121,16 +121,16 @@ namespace Microsoft.AspNetCore.Routing
options: options); options: options);
} }
public override string GetUriByAddress<TAddress>( public override string? GetUriByAddress<TAddress>(
HttpContext httpContext, HttpContext httpContext,
TAddress address, TAddress address,
RouteValueDictionary values, RouteValueDictionary values,
RouteValueDictionary ambientValues = default, RouteValueDictionary? ambientValues = default,
string scheme = default, string? scheme = default,
HostString? host = default, HostString? host = default,
PathString? pathBase = default, PathString? pathBase = default,
FragmentString fragment = default, FragmentString fragment = default,
LinkOptions options = null) LinkOptions? options = null)
{ {
if (httpContext == null) if (httpContext == null)
{ {
@ -154,14 +154,14 @@ namespace Microsoft.AspNetCore.Routing
options); options);
} }
public override string GetUriByAddress<TAddress>( public override string? GetUriByAddress<TAddress>(
TAddress address, TAddress address,
RouteValueDictionary values, RouteValueDictionary values,
string scheme, string scheme,
HostString host, HostString host,
PathString pathBase = default, PathString pathBase = default,
FragmentString fragment = default, FragmentString fragment = default,
LinkOptions options = null) LinkOptions? options = null)
{ {
if (string.IsNullOrEmpty(scheme)) if (string.IsNullOrEmpty(scheme))
{ {
@ -207,14 +207,14 @@ namespace Microsoft.AspNetCore.Routing
return endpoints; return endpoints;
} }
private string GetPathByEndpoints( private string? GetPathByEndpoints(
HttpContext httpContext, HttpContext? httpContext,
List<RouteEndpoint> endpoints, List<RouteEndpoint> endpoints,
RouteValueDictionary values, RouteValueDictionary values,
RouteValueDictionary ambientValues, RouteValueDictionary? ambientValues,
PathString pathBase, PathString pathBase,
FragmentString fragment, FragmentString fragment,
LinkOptions options) LinkOptions? options)
{ {
for (var i = 0; i < endpoints.Count; i++) for (var i = 0; i < endpoints.Count; i++)
{ {
@ -242,15 +242,15 @@ namespace Microsoft.AspNetCore.Routing
} }
// Also called from DefaultLinkGenerationTemplate // Also called from DefaultLinkGenerationTemplate
public string GetUriByEndpoints( public string? GetUriByEndpoints(
List<RouteEndpoint> endpoints, List<RouteEndpoint> endpoints,
RouteValueDictionary values, RouteValueDictionary values,
RouteValueDictionary ambientValues, RouteValueDictionary? ambientValues,
string scheme, string scheme,
HostString host, HostString host,
PathString pathBase, PathString pathBase,
FragmentString fragment, FragmentString fragment,
LinkOptions options) LinkOptions? options)
{ {
for (var i = 0; i < endpoints.Count; i++) for (var i = 0; i < endpoints.Count; i++)
{ {
@ -289,11 +289,11 @@ namespace Microsoft.AspNetCore.Routing
// Internal for testing // Internal for testing
internal bool TryProcessTemplate( internal bool TryProcessTemplate(
HttpContext httpContext, HttpContext? httpContext,
RouteEndpoint endpoint, RouteEndpoint endpoint,
RouteValueDictionary values, RouteValueDictionary values,
RouteValueDictionary ambientValues, RouteValueDictionary? ambientValues,
LinkOptions options, LinkOptions? options,
out (PathString path, QueryString query) result) out (PathString path, QueryString query) result)
{ {
var templateBinder = GetTemplateBinder(endpoint); var templateBinder = GetTemplateBinder(endpoint);
@ -325,7 +325,7 @@ namespace Microsoft.AspNetCore.Routing
} }
// Also called from DefaultLinkGenerationTemplate // Also called from DefaultLinkGenerationTemplate
public static RouteValueDictionary GetAmbientValues(HttpContext httpContext) public static RouteValueDictionary? GetAmbientValues(HttpContext httpContext)
{ {
return httpContext?.Features.Get<IRouteValuesFeature>()?.RouteValues; return httpContext?.Features.Get<IRouteValuesFeature>()?.RouteValues;
} }
@ -335,6 +335,7 @@ namespace Microsoft.AspNetCore.Routing
_cache.Dispose(); _cache.Dispose();
} }
#nullable disable
private static class Log private static class Log
{ {
public static class EventIds public static class EventIds

View File

@ -13,6 +13,6 @@ namespace Microsoft.AspNetCore.Routing
/// </summary> /// </summary>
/// <param name="inlineConstraint">The inline constraint to resolve.</param> /// <param name="inlineConstraint">The inline constraint to resolve.</param>
/// <returns>The <see cref="IRouteConstraint"/> the inline constraint was resolved to.</returns> /// <returns>The <see cref="IRouteConstraint"/> the inline constraint was resolved to.</returns>
IRouteConstraint ResolveConstraint(string inlineConstraint); IRouteConstraint? ResolveConstraint(string inlineConstraint);
} }
} }

View File

@ -5,6 +5,6 @@ namespace Microsoft.AspNetCore.Routing
{ {
public interface INamedRouter : IRouter public interface INamedRouter : IRouter
{ {
string Name { get; } string? Name { get; }
} }
} }

View File

@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Routing
/// Gets or sets the default <see cref="IRouter"/> that is used as a handler if an <see cref="IRouter"/> /// Gets or sets the default <see cref="IRouter"/> that is used as a handler if an <see cref="IRouter"/>
/// is added to the list of routes but does not specify its own. /// is added to the list of routes but does not specify its own.
/// </summary> /// </summary>
IRouter DefaultHandler { get; set; } IRouter? DefaultHandler { get; set; }
/// <summary> /// <summary>
/// Gets the sets the <see cref="IServiceProvider"/> used to resolve services for routes. /// Gets the sets the <see cref="IServiceProvider"/> used to resolve services for routes.
@ -39,4 +39,4 @@ namespace Microsoft.AspNetCore.Routing
/// </summary> /// </summary>
IRouter Build(); IRouter Build();
} }
} }

View File

@ -1,6 +1,8 @@
// 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System; using System;
using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Constraints; using Microsoft.AspNetCore.Routing.Constraints;
@ -22,8 +24,8 @@ namespace Microsoft.AspNetCore.Builder
/// <returns>A reference to this instance after the operation has completed.</returns> /// <returns>A reference to this instance after the operation has completed.</returns>
public static IRouteBuilder MapRoute( public static IRouteBuilder MapRoute(
this IRouteBuilder routeBuilder, this IRouteBuilder routeBuilder,
string name, string? name,
string template) string? template)
{ {
MapRoute(routeBuilder, name, template, defaults: null); MapRoute(routeBuilder, name, template, defaults: null);
return routeBuilder; return routeBuilder;
@ -42,9 +44,9 @@ namespace Microsoft.AspNetCore.Builder
/// <returns>A reference to this instance after the operation has completed.</returns> /// <returns>A reference to this instance after the operation has completed.</returns>
public static IRouteBuilder MapRoute( public static IRouteBuilder MapRoute(
this IRouteBuilder routeBuilder, this IRouteBuilder routeBuilder,
string name, string? name,
string template, string? template,
object defaults) object? defaults)
{ {
return MapRoute(routeBuilder, name, template, defaults, constraints: null); return MapRoute(routeBuilder, name, template, defaults, constraints: null);
} }
@ -67,10 +69,10 @@ namespace Microsoft.AspNetCore.Builder
/// <returns>A reference to this instance after the operation has completed.</returns> /// <returns>A reference to this instance after the operation has completed.</returns>
public static IRouteBuilder MapRoute( public static IRouteBuilder MapRoute(
this IRouteBuilder routeBuilder, this IRouteBuilder routeBuilder,
string name, string? name,
string template, string? template,
object defaults, object? defaults,
object constraints) object? constraints)
{ {
return MapRoute(routeBuilder, name, template, defaults, constraints, dataTokens: null); return MapRoute(routeBuilder, name, template, defaults, constraints, dataTokens: null);
} }
@ -97,11 +99,11 @@ namespace Microsoft.AspNetCore.Builder
/// <returns>A reference to this instance after the operation has completed.</returns> /// <returns>A reference to this instance after the operation has completed.</returns>
public static IRouteBuilder MapRoute( public static IRouteBuilder MapRoute(
this IRouteBuilder routeBuilder, this IRouteBuilder routeBuilder,
string name, string? name,
string template, string? template,
object defaults, object? defaults,
object constraints, object? constraints,
object dataTokens) object? dataTokens)
{ {
if (routeBuilder.DefaultHandler == null) if (routeBuilder.DefaultHandler == null)
{ {
@ -113,7 +115,7 @@ namespace Microsoft.AspNetCore.Builder
name, name,
template, template,
new RouteValueDictionary(defaults), new RouteValueDictionary(defaults),
new RouteValueDictionary(constraints), new RouteValueDictionary(constraints)!,
new RouteValueDictionary(dataTokens), new RouteValueDictionary(dataTokens),
CreateInlineConstraintResolver(routeBuilder.ServiceProvider))); CreateInlineConstraintResolver(routeBuilder.ServiceProvider)));
@ -144,7 +146,7 @@ namespace Microsoft.AspNetCore.Builder
_parameterPolicyFactory = parameterPolicyFactory; _parameterPolicyFactory = parameterPolicyFactory;
} }
public IRouteConstraint ResolveConstraint(string inlineConstraint) public IRouteConstraint? ResolveConstraint(string inlineConstraint)
{ {
var routeConstraint = _inner.ResolveConstraint(inlineConstraint); var routeConstraint = _inner.ResolveConstraint(inlineConstraint);
if (routeConstraint != null) if (routeConstraint != null)

View File

@ -1,6 +1,8 @@
// 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -17,7 +19,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
public sealed class EndpointMetadataComparer : IComparer<Endpoint> public sealed class EndpointMetadataComparer : IComparer<Endpoint>
{ {
private IServiceProvider _services; private IServiceProvider _services;
private IComparer<Endpoint>[] _comparers; private IComparer<Endpoint>[]? _comparers;
// This type is **INTENDED** for use in MatcherPolicy instances yet is also needs the MatcherPolicy instances. // This type is **INTENDED** for use in MatcherPolicy instances yet is also needs the MatcherPolicy instances.
// using IServiceProvider to break the cycle. // using IServiceProvider to break the cycle.
@ -48,7 +50,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
} }
} }
int IComparer<Endpoint>.Compare(Endpoint x, Endpoint y) int IComparer<Endpoint>.Compare(Endpoint? x, Endpoint? y)
{ {
if (x == null) if (x == null)
{ {
@ -75,7 +77,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
} }
/// <summary> /// <summary>
/// A base class for <see cref="IComparer{Endpoint}"/> implementations that use /// A base class for <see cref="IComparer{Endpoint}"/> implementations that use
/// a specific type of metadata from <see cref="Endpoint.Metadata"/> for comparison. /// a specific type of metadata from <see cref="Endpoint.Metadata"/> for comparison.
/// Useful for implementing <see cref="IEndpointComparerPolicy.Comparer"/>. /// Useful for implementing <see cref="IEndpointComparerPolicy.Comparer"/>.
/// </summary> /// </summary>
@ -88,17 +90,17 @@ namespace Microsoft.AspNetCore.Routing.Matching
public static readonly EndpointMetadataComparer<TMetadata> Default = new DefaultComparer<TMetadata>(); public static readonly EndpointMetadataComparer<TMetadata> Default = new DefaultComparer<TMetadata>();
/// <summary> /// <summary>
/// Compares two objects and returns a value indicating whether one is less than, equal to, /// Compares two objects and returns a value indicating whether one is less than, equal to,
/// or greater than the other. /// or greater than the other.
/// </summary> /// </summary>
/// <param name="x">The first object to compare.</param> /// <param name="x">The first object to compare.</param>
/// <param name="y">The second object to compare.</param> /// <param name="y">The second object to compare.</param>
/// <returns> /// <returns>
/// An implementation of this method must return a value less than zero if /// An implementation of this method must return a value less than zero if
/// x is less than y, zero if x is equal to y, or a value greater than zero if x is /// x is less than y, zero if x is equal to y, or a value greater than zero if x is
/// greater than y. /// greater than y.
/// </returns> /// </returns>
public int Compare(Endpoint x, Endpoint y) public int Compare(Endpoint? x, Endpoint? y)
{ {
if (x == null) if (x == null)
{ {
@ -118,7 +120,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
/// </summary> /// </summary>
/// <param name="endpoint">The <see cref="Endpoint"/>.</param> /// <param name="endpoint">The <see cref="Endpoint"/>.</param>
/// <returns>The <typeparamref name="TMetadata"/> instance or <c>null</c>.</returns> /// <returns>The <typeparamref name="TMetadata"/> instance or <c>null</c>.</returns>
protected virtual TMetadata GetMetadata(Endpoint endpoint) protected virtual TMetadata? GetMetadata(Endpoint endpoint)
{ {
return endpoint.Metadata.GetMetadata<TMetadata>(); return endpoint.Metadata.GetMetadata<TMetadata>();
} }
@ -129,8 +131,8 @@ namespace Microsoft.AspNetCore.Routing.Matching
/// <param name="x">The first object to compare.</param> /// <param name="x">The first object to compare.</param>
/// <param name="y">The second object to compare.</param> /// <param name="y">The second object to compare.</param>
/// <returns> /// <returns>
/// An implementation of this method must return a value less than zero if /// An implementation of this method must return a value less than zero if
/// x is less than y, zero if x is equal to y, or a value greater than zero if x is /// x is less than y, zero if x is equal to y, or a value greater than zero if x is
/// greater than y. /// greater than y.
/// </returns> /// </returns>
/// <remarks> /// <remarks>
@ -139,7 +141,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
/// compared, the endpoint that defines an instance of <typeparamref name="TMetadata"/> /// compared, the endpoint that defines an instance of <typeparamref name="TMetadata"/>
/// will be considered higher priority. /// will be considered higher priority.
/// </remarks> /// </remarks>
protected virtual int CompareMetadata(TMetadata x, TMetadata y) protected virtual int CompareMetadata(TMetadata? x, TMetadata? y)
{ {
// The default policy is that if x endpoint defines TMetadata, and // The default policy is that if x endpoint defines TMetadata, and
// y endpoint does not, then x is *more specific* than y. We return // y endpoint does not, then x is *more specific* than y. We return

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<Description>ASP.NET Core middleware for routing requests to application logic and for generating links. <Description>ASP.NET Core middleware for routing requests to application logic and for generating links.
@ -21,6 +21,7 @@ Microsoft.AspNetCore.Routing.RouteCollection</Description>
--> -->
<ILEmitSaveAssemblies Condition="'$(ILEmitSaveAssemblies)'==''">false</ILEmitSaveAssemblies> <ILEmitSaveAssemblies Condition="'$(ILEmitSaveAssemblies)'==''">false</ILEmitSaveAssemblies>
<DefineConstants Condition="'$(ILEmitSaveAssemblies)'=='true'">IL_EMIT_SAVE_ASSEMBLIES;$(DefineConstants)</DefineConstants> <DefineConstants Condition="'$(ILEmitSaveAssemblies)'=='true'">IL_EMIT_SAVE_ASSEMBLIES;$(DefineConstants)</DefineConstants>
<LangVersion>preview</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@ -28,7 +29,7 @@ Microsoft.AspNetCore.Routing.RouteCollection</Description>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Reference Include="Microsoft.AspNetCore.Authorization" /> <Reference Include="Microsoft.AspNetCore.Authorization" />
<Reference Include="Microsoft.AspNetCore.Http.Extensions" /> <Reference Include="Microsoft.AspNetCore.Http.Extensions" />
<Reference Include="Microsoft.AspNetCore.Routing.Abstractions" /> <Reference Include="Microsoft.AspNetCore.Routing.Abstractions" />
<Reference Include="Microsoft.Extensions.Logging.Abstractions" /> <Reference Include="Microsoft.Extensions.Logging.Abstractions" />

View File

@ -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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System; using System;
@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Routing
/// <param name="parameter">The parameter the parameter policy is being created for.</param> /// <param name="parameter">The parameter the parameter policy is being created for.</param>
/// <param name="inlineText">The inline text to resolve.</param> /// <param name="inlineText">The inline text to resolve.</param>
/// <returns>The <see cref="IParameterPolicy"/> for the parameter.</returns> /// <returns>The <see cref="IParameterPolicy"/> for the parameter.</returns>
public abstract IParameterPolicy Create(RoutePatternParameterPart parameter, string inlineText); public abstract IParameterPolicy Create(RoutePatternParameterPart? parameter, string inlineText);
/// <summary> /// <summary>
/// Creates a parameter policy. /// Creates a parameter policy.

View File

@ -231,4 +231,7 @@
<data name="DuplicateEndpointNameHeader" xml:space="preserve"> <data name="DuplicateEndpointNameHeader" xml:space="preserve">
<value>The following endpoints with a duplicate endpoint name were found.</value> <value>The following endpoints with a duplicate endpoint name were found.</value>
</data> </data>
<data name="FormatterMapping_MediaTypeInvalid" xml:space="preserve">
<value>No media type found for format '{0}'.</value>
</data>
</root> </root>

View File

@ -1,6 +1,8 @@
// 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -28,9 +30,9 @@ namespace Microsoft.AspNetCore.Routing
public Route( public Route(
IRouter target, IRouter target,
string routeTemplate, string routeTemplate,
RouteValueDictionary defaults, RouteValueDictionary? defaults,
IDictionary<string, object> constraints, IDictionary<string, object>? constraints,
RouteValueDictionary dataTokens, RouteValueDictionary? dataTokens,
IInlineConstraintResolver inlineConstraintResolver) IInlineConstraintResolver inlineConstraintResolver)
: this(target, null, routeTemplate, defaults, constraints, dataTokens, inlineConstraintResolver) : this(target, null, routeTemplate, defaults, constraints, dataTokens, inlineConstraintResolver)
{ {
@ -38,11 +40,11 @@ namespace Microsoft.AspNetCore.Routing
public Route( public Route(
IRouter target, IRouter target,
string routeName, string? routeName,
string routeTemplate, string? routeTemplate,
RouteValueDictionary defaults, RouteValueDictionary? defaults,
IDictionary<string, object> constraints, IDictionary<string, object>? constraints,
RouteValueDictionary dataTokens, RouteValueDictionary? dataTokens,
IInlineConstraintResolver inlineConstraintResolver) IInlineConstraintResolver inlineConstraintResolver)
: base( : base(
routeTemplate, routeTemplate,
@ -68,7 +70,7 @@ namespace Microsoft.AspNetCore.Routing
return _target.RouteAsync(context); return _target.RouteAsync(context);
} }
protected override VirtualPathData OnVirtualPathGenerated(VirtualPathContext context) protected override VirtualPathData? OnVirtualPathGenerated(VirtualPathContext context)
{ {
return _target.GetVirtualPath(context); return _target.GetVirtualPath(context);
} }

View File

@ -1,8 +1,12 @@
// 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing.Logging; using Microsoft.AspNetCore.Routing.Logging;
@ -16,18 +20,18 @@ namespace Microsoft.AspNetCore.Routing
{ {
private readonly object _loggersLock = new object(); private readonly object _loggersLock = new object();
private TemplateMatcher _matcher; private TemplateMatcher? _matcher;
private TemplateBinder _binder; private TemplateBinder? _binder;
private ILogger _logger; private ILogger? _logger;
private ILogger _constraintLogger; private ILogger? _constraintLogger;
public RouteBase( public RouteBase(
string template, string? template,
string name, string? name,
IInlineConstraintResolver constraintResolver, IInlineConstraintResolver constraintResolver,
RouteValueDictionary defaults, RouteValueDictionary? defaults,
IDictionary<string, object> constraints, IDictionary<string, object>? constraints,
RouteValueDictionary dataTokens) RouteValueDictionary? dataTokens)
{ {
if (constraintResolver == null) if (constraintResolver == null)
{ {
@ -62,13 +66,13 @@ namespace Microsoft.AspNetCore.Routing
public virtual RouteValueDictionary Defaults { get; protected set; } public virtual RouteValueDictionary Defaults { get; protected set; }
public virtual string Name { get; protected set; } public virtual string? Name { get; protected set; }
public virtual RouteTemplate ParsedTemplate { get; protected set; } public virtual RouteTemplate ParsedTemplate { get; protected set; }
protected abstract Task OnRouteMatched(RouteContext context); protected abstract Task OnRouteMatched(RouteContext context);
protected abstract VirtualPathData OnVirtualPathGenerated(VirtualPathContext context); protected abstract VirtualPathData? OnVirtualPathGenerated(VirtualPathContext context);
/// <inheritdoc /> /// <inheritdoc />
public virtual Task RouteAsync(RouteContext context) public virtual Task RouteAsync(RouteContext context)
@ -106,13 +110,13 @@ namespace Microsoft.AspNetCore.Routing
{ {
return Task.CompletedTask; return Task.CompletedTask;
} }
_logger.RequestMatchedRoute(Name, ParsedTemplate.TemplateText); _logger.RequestMatchedRoute(Name!, ParsedTemplate.TemplateText);
return OnRouteMatched(context); return OnRouteMatched(context);
} }
/// <inheritdoc /> /// <inheritdoc />
public virtual VirtualPathData GetVirtualPath(VirtualPathContext context) public virtual VirtualPathData? GetVirtualPath(VirtualPathContext context)
{ {
EnsureBinder(context.HttpContext); EnsureBinder(context.HttpContext);
EnsureLoggers(context.HttpContext); EnsureLoggers(context.HttpContext);
@ -169,7 +173,7 @@ namespace Microsoft.AspNetCore.Routing
protected static IDictionary<string, IRouteConstraint> GetConstraints( protected static IDictionary<string, IRouteConstraint> GetConstraints(
IInlineConstraintResolver inlineConstraintResolver, IInlineConstraintResolver inlineConstraintResolver,
RouteTemplate parsedTemplate, RouteTemplate parsedTemplate,
IDictionary<string, object> constraints) IDictionary<string, object>? constraints)
{ {
var constraintBuilder = new RouteConstraintBuilder(inlineConstraintResolver, parsedTemplate.TemplateText); var constraintBuilder = new RouteConstraintBuilder(inlineConstraintResolver, parsedTemplate.TemplateText);
@ -199,7 +203,7 @@ namespace Microsoft.AspNetCore.Routing
protected static RouteValueDictionary GetDefaults( protected static RouteValueDictionary GetDefaults(
RouteTemplate parsedTemplate, RouteTemplate parsedTemplate,
RouteValueDictionary defaults) RouteValueDictionary? defaults)
{ {
var result = defaults == null ? new RouteValueDictionary() : new RouteValueDictionary(defaults); var result = defaults == null ? new RouteValueDictionary() : new RouteValueDictionary(defaults);
@ -245,6 +249,7 @@ namespace Microsoft.AspNetCore.Routing
} }
} }
[MemberNotNull(nameof(_binder))]
private void EnsureBinder(HttpContext context) private void EnsureBinder(HttpContext context)
{ {
if (_binder == null) if (_binder == null)
@ -254,6 +259,7 @@ namespace Microsoft.AspNetCore.Routing
} }
} }
[MemberNotNull(nameof(_logger), nameof(_constraintLogger))]
private void EnsureLoggers(HttpContext context) private void EnsureLoggers(HttpContext context)
{ {
// We check first using the _logger to see if the loggers have been initialized to avoid taking // We check first using the _logger to see if the loggers have been initialized to avoid taking
@ -268,6 +274,8 @@ namespace Microsoft.AspNetCore.Routing
// Multiple threads might have tried to acquire the lock at the same time. Technically // Multiple threads might have tried to acquire the lock at the same time. Technically
// there is nothing wrong if things get reinitialized by a second thread, but its easy // there is nothing wrong if things get reinitialized by a second thread, but its easy
// to prevent by just rechecking and returning here. // to prevent by just rechecking and returning here.
Debug.Assert(_constraintLogger != null);
return; return;
} }
@ -275,9 +283,13 @@ namespace Microsoft.AspNetCore.Routing
_constraintLogger = factory.CreateLogger(typeof(RouteConstraintMatcher).FullName); _constraintLogger = factory.CreateLogger(typeof(RouteConstraintMatcher).FullName);
_logger = factory.CreateLogger(typeof(RouteBase).FullName); _logger = factory.CreateLogger(typeof(RouteBase).FullName);
} }
} }
Debug.Assert(_constraintLogger != null);
} }
[MemberNotNull(nameof(_matcher))]
private void EnsureMatcher() private void EnsureMatcher()
{ {
if (_matcher == null) if (_matcher == null)

View File

@ -1,6 +1,8 @@
// 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
@ -15,7 +17,7 @@ namespace Microsoft.AspNetCore.Routing
{ {
} }
public RouteBuilder(IApplicationBuilder applicationBuilder, IRouter defaultHandler) public RouteBuilder(IApplicationBuilder applicationBuilder, IRouter? defaultHandler)
{ {
if (applicationBuilder == null) if (applicationBuilder == null)
{ {
@ -39,7 +41,7 @@ namespace Microsoft.AspNetCore.Routing
public IApplicationBuilder ApplicationBuilder { get; } public IApplicationBuilder ApplicationBuilder { get; }
public IRouter DefaultHandler { get; set; } public IRouter? DefaultHandler { get; set; }
public IServiceProvider ServiceProvider { get; } public IServiceProvider ServiceProvider { get; }

View File

@ -1,8 +1,12 @@
// 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -18,7 +22,7 @@ namespace Microsoft.AspNetCore.Routing
private readonly Dictionary<string, INamedRouter> _namedRoutes = private readonly Dictionary<string, INamedRouter> _namedRoutes =
new Dictionary<string, INamedRouter>(StringComparer.OrdinalIgnoreCase); new Dictionary<string, INamedRouter>(StringComparer.OrdinalIgnoreCase);
private RouteOptions _options; private RouteOptions? _options;
public IRouter this[int index] public IRouter this[int index]
{ {
@ -84,13 +88,13 @@ namespace Microsoft.AspNetCore.Routing
} }
} }
public virtual VirtualPathData GetVirtualPath(VirtualPathContext context) public virtual VirtualPathData? GetVirtualPath(VirtualPathContext context)
{ {
EnsureOptions(context.HttpContext); EnsureOptions(context.HttpContext);
if (!string.IsNullOrEmpty(context.RouteName)) if (!string.IsNullOrEmpty(context.RouteName))
{ {
VirtualPathData namedRoutePathData = null; VirtualPathData? namedRoutePathData = null;
if (_namedRoutes.TryGetValue(context.RouteName, out var matchedNamedRoute)) if (_namedRoutes.TryGetValue(context.RouteName, out var matchedNamedRoute))
{ {
@ -114,7 +118,7 @@ namespace Microsoft.AspNetCore.Routing
} }
} }
private VirtualPathData GetVirtualPath(VirtualPathContext context, List<IRouter> routes) private VirtualPathData? GetVirtualPath(VirtualPathContext context, List<IRouter> routes)
{ {
for (var i = 0; i < routes.Count; i++) for (var i = 0; i < routes.Count; i++)
{ {
@ -130,13 +134,15 @@ namespace Microsoft.AspNetCore.Routing
return null; return null;
} }
private VirtualPathData NormalizeVirtualPath(VirtualPathData pathData) private VirtualPathData? NormalizeVirtualPath(VirtualPathData? pathData)
{ {
if (pathData == null) if (pathData == null)
{ {
return pathData; return pathData;
} }
Debug.Assert(_options != null);
var url = pathData.VirtualPath; var url = pathData.VirtualPath;
if (!string.IsNullOrEmpty(url) && (_options.LowercaseUrls || _options.AppendTrailingSlash)) if (!string.IsNullOrEmpty(url) && (_options.LowercaseUrls || _options.AppendTrailingSlash))
@ -175,6 +181,7 @@ namespace Microsoft.AspNetCore.Routing
return pathData; return pathData;
} }
[MemberNotNull(nameof(_options))]
private void EnsureOptions(HttpContext context) private void EnsureOptions(HttpContext context)
{ {
if (_options == null) if (_options == null)

View File

@ -1,6 +1,8 @@
// 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
@ -20,7 +22,7 @@ namespace Microsoft.AspNetCore.Routing
return _requestDelegate; return _requestDelegate;
} }
public VirtualPathData GetVirtualPath(VirtualPathContext context) public VirtualPathData? GetVirtualPath(VirtualPathContext context)
{ {
// Nothing to do. // Nothing to do.
return null; return null;

View File

@ -1,6 +1,8 @@
// 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
namespace Microsoft.AspNetCore.Routing namespace Microsoft.AspNetCore.Routing
{ {
/// <summary> /// <summary>
@ -11,16 +13,16 @@ namespace Microsoft.AspNetCore.Routing
/// <summary> /// <summary>
/// Gets or sets the route name. /// Gets or sets the route name.
/// </summary> /// </summary>
public string RouteName { get; set; } public string? RouteName { get; set; }
/// <summary> /// <summary>
/// Gets or sets the route values that are explicitly specified. /// Gets or sets the route values that are explicitly specified.
/// </summary> /// </summary>
public RouteValueDictionary ExplicitValues { get; set; } public RouteValueDictionary ExplicitValues { get; set; } = default!;
/// <summary> /// <summary>
/// Gets or sets ambient route values from the current HTTP request. /// Gets or sets ambient route values from the current HTTP request.
/// </summary> /// </summary>
public RouteValueDictionary AmbientValues { get; set; } public RouteValueDictionary? AmbientValues { get; set; }
} }
} }

View File

@ -5,6 +5,6 @@ namespace Microsoft.AspNetCore.Routing
{ {
public class RoutingFeature : IRoutingFeature public class RoutingFeature : IRoutingFeature
{ {
public RouteData RouteData { get; set; } public RouteData? RouteData { get; set; }
} }
} }

View File

@ -1,6 +1,8 @@
// 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;

View File

@ -1,6 +1,8 @@
// 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
@ -72,7 +74,7 @@ namespace Microsoft.AspNetCore.Routing.Template
public IList<TemplateSegment> Segments { get; } public IList<TemplateSegment> Segments { get; }
public TemplateSegment GetSegment(int index) public TemplateSegment? GetSegment(int index)
{ {
if (index < 0) if (index < 0)
{ {
@ -92,7 +94,7 @@ namespace Microsoft.AspNetCore.Routing.Template
/// </summary> /// </summary>
/// <param name="name">The name of the parameter to match.</param> /// <param name="name">The name of the parameter to match.</param>
/// <returns>The matching parameter or <c>null</c> if no parameter matches the given name.</returns> /// <returns>The matching parameter or <c>null</c> if no parameter matches the given name.</returns>
public TemplatePart GetParameter(string name) public TemplatePart? GetParameter(string name)
{ {
for (var i = 0; i < Parameters.Count; i++) for (var i = 0; i < Parameters.Count; i++)
{ {

View File

@ -1,6 +1,8 @@
// 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
@ -21,8 +23,8 @@ namespace Microsoft.AspNetCore.Routing.Template
private readonly ObjectPool<UriBuildingContext> _pool; private readonly ObjectPool<UriBuildingContext> _pool;
private readonly (string parameterName, IRouteConstraint constraint)[] _constraints; private readonly (string parameterName, IRouteConstraint constraint)[] _constraints;
private readonly RouteValueDictionary _defaults; private readonly RouteValueDictionary? _defaults;
private readonly KeyValuePair<string, object>[] _filters; private readonly KeyValuePair<string, object?>[] _filters;
private readonly (string parameterName, IOutboundParameterTransformer transformer)[] _parameterTransformers; private readonly (string parameterName, IOutboundParameterTransformer transformer)[] _parameterTransformers;
private readonly RoutePattern _pattern; private readonly RoutePattern _pattern;
private readonly string[] _requiredKeys; private readonly string[] _requiredKeys;
@ -30,7 +32,7 @@ namespace Microsoft.AspNetCore.Routing.Template
// A pre-allocated template for the 'known' route values that this template binder uses. // A pre-allocated template for the 'known' route values that this template binder uses.
// //
// We always make a copy of this and operate on the copy, so that we don't mutate shared state. // We always make a copy of this and operate on the copy, so that we don't mutate shared state.
private readonly KeyValuePair<string, object>[] _slots; private readonly KeyValuePair<string, object?>[] _slots;
/// <summary> /// <summary>
/// Creates a new instance of <see cref="TemplateBinder"/>. /// Creates a new instance of <see cref="TemplateBinder"/>.
@ -44,7 +46,7 @@ namespace Microsoft.AspNetCore.Routing.Template
ObjectPool<UriBuildingContext> pool, ObjectPool<UriBuildingContext> pool,
RouteTemplate template, RouteTemplate template,
RouteValueDictionary defaults) RouteValueDictionary defaults)
: this(urlEncoder, pool, template?.ToRoutePattern(), defaults, requiredKeys: null, parameterPolicies: null) : this(urlEncoder, pool, template?.ToRoutePattern()!, defaults, requiredKeys: null, parameterPolicies: null)
{ {
} }
@ -63,9 +65,9 @@ namespace Microsoft.AspNetCore.Routing.Template
UrlEncoder urlEncoder, UrlEncoder urlEncoder,
ObjectPool<UriBuildingContext> pool, ObjectPool<UriBuildingContext> pool,
RoutePattern pattern, RoutePattern pattern,
RouteValueDictionary defaults, RouteValueDictionary? defaults,
IEnumerable<string> requiredKeys, IEnumerable<string>? requiredKeys,
IEnumerable<(string parameterName, IParameterPolicy policy)> parameterPolicies) IEnumerable<(string parameterName, IParameterPolicy policy)>? parameterPolicies)
{ {
if (urlEncoder == null) if (urlEncoder == null)
{ {
@ -160,11 +162,11 @@ namespace Microsoft.AspNetCore.Routing.Template
} }
// Step 1: Get the list of values we're going to try to use to match and generate this URI // Step 1: Get the list of values we're going to try to use to match and generate this URI
public TemplateValuesResult GetValues(RouteValueDictionary ambientValues, RouteValueDictionary values) public TemplateValuesResult? GetValues(RouteValueDictionary? ambientValues, RouteValueDictionary values)
{ {
// Make a new copy of the slots array, we'll use this as 'scratch' space // Make a new copy of the slots array, we'll use this as 'scratch' space
// and then the RVD will take ownership of it. // and then the RVD will take ownership of it.
var slots = new KeyValuePair<string, object>[_slots.Length]; var slots = new KeyValuePair<string, object?>[_slots.Length];
Array.Copy(_slots, 0, slots, 0, slots.Length); Array.Copy(_slots, 0, slots, 0, slots.Length);
// Keeping track of the number of 'values' we've processed can be used to avoid doing // Keeping track of the number of 'values' we've processed can be used to avoid doing
@ -184,7 +186,7 @@ namespace Microsoft.AspNetCore.Routing.Template
// with null values, we use the null-object-pattern to track 'explicit null', which means that // with null values, we use the null-object-pattern to track 'explicit null', which means that
// null means omitted. // null means omitted.
value = IsRoutePartNonEmpty(value) ? value : SentinullValue.Instance; value = IsRoutePartNonEmpty(value) ? value : SentinullValue.Instance;
slots[i] = new KeyValuePair<string, object>(key, value); slots[i] = new KeyValuePair<string, object?>(key, value);
// Track the count of processed values - this allows a fast path later. // Track the count of processed values - this allows a fast path later.
valueProcessedCount++; valueProcessedCount++;
@ -266,7 +268,7 @@ namespace Microsoft.AspNetCore.Routing.Template
var hasExplicitValue = value != null; var hasExplicitValue = value != null;
var hasAmbientValue = false; var hasAmbientValue = false;
var ambientValue = (object)null; var ambientValue = (object?)null;
var parameter = parameters[i]; var parameter = parameters[i];
@ -318,7 +320,7 @@ namespace Microsoft.AspNetCore.Routing.Template
(RoutePartsEqual(requiredValue, ambientValue) || RoutePattern.IsRequiredValueAny(requiredValue))) (RoutePartsEqual(requiredValue, ambientValue) || RoutePattern.IsRequiredValueAny(requiredValue)))
{ {
// Treat this an an explicit value to *force it*. // Treat this an an explicit value to *force it*.
slots[i] = new KeyValuePair<string, object>(key, ambientValue); slots[i] = new KeyValuePair<string, object?>(key, ambientValue);
hasExplicitValue = true; hasExplicitValue = true;
value = ambientValue; value = ambientValue;
} }
@ -331,7 +333,7 @@ namespace Microsoft.AspNetCore.Routing.Template
} }
else if (copyAmbientValues && hasAmbientValue) else if (copyAmbientValues && hasAmbientValue)
{ {
slots[i] = new KeyValuePair<string, object>(key, ambientValue); slots[i] = new KeyValuePair<string, object?>(key, ambientValue);
} }
else if (parameter.IsOptional || parameter.IsCatchAll) else if (parameter.IsOptional || parameter.IsCatchAll)
{ {
@ -344,7 +346,7 @@ namespace Microsoft.AspNetCore.Routing.Template
// Add the default value only if there isn't already a new value for it and // Add the default value only if there isn't already a new value for it and
// only if it actually has a default value. // only if it actually has a default value.
slots[i] = new KeyValuePair<string, object>(key, defaultValue); slots[i] = new KeyValuePair<string, object?>(key, defaultValue);
} }
else else
{ {
@ -392,7 +394,7 @@ namespace Microsoft.AspNetCore.Routing.Template
// the dictionary. // the dictionary.
foreach (var kvp in values) foreach (var kvp in values)
{ {
if (!_defaults.ContainsKey(kvp.Key)) if (!_defaults!.ContainsKey(kvp.Key))
{ {
#if RVD_TryAdd #if RVD_TryAdd
acceptedValues.TryAdd(kvp.Key, kvp.Value); acceptedValues.TryAdd(kvp.Key, kvp.Value);
@ -428,7 +430,7 @@ namespace Microsoft.AspNetCore.Routing.Template
// Processes the constraints **if** they were passed in to the TemplateBinder constructor. // Processes the constraints **if** they were passed in to the TemplateBinder constructor.
// Returns true on success // Returns true on success
// Returns false + sets the name/constraint for logging on failure. // Returns false + sets the name/constraint for logging on failure.
public bool TryProcessConstraints(HttpContext httpContext, RouteValueDictionary combinedValues, out string parameterName, out IRouteConstraint constraint) public bool TryProcessConstraints(HttpContext? httpContext, RouteValueDictionary combinedValues, out string? parameterName, out IRouteConstraint? constraint)
{ {
var constraints = _constraints; var constraints = _constraints;
for (var i = 0; i < constraints.Length; i++) for (var i = 0; i < constraints.Length; i++)
@ -447,7 +449,7 @@ namespace Microsoft.AspNetCore.Routing.Template
} }
// Step 2: If the route is a match generate the appropriate URI // Step 2: If the route is a match generate the appropriate URI
public string BindValues(RouteValueDictionary acceptedValues) public string? BindValues(RouteValueDictionary acceptedValues)
{ {
var context = _pool.Get(); var context = _pool.Get();
@ -464,7 +466,7 @@ namespace Microsoft.AspNetCore.Routing.Template
// Step 2: If the route is a match generate the appropriate URI // Step 2: If the route is a match generate the appropriate URI
internal bool TryBindValues( internal bool TryBindValues(
RouteValueDictionary acceptedValues, RouteValueDictionary acceptedValues,
LinkOptions options, LinkOptions? options,
LinkOptions globalOptions, LinkOptions globalOptions,
out (PathString path, QueryString query) result) out (PathString path, QueryString query) result)
{ {
@ -519,7 +521,6 @@ namespace Microsoft.AspNetCore.Routing.Template
for (var j = 0; j < partsCount; j++) for (var j = 0; j < partsCount; j++)
{ {
var part = parts[j]; var part = parts[j];
if (part is RoutePatternLiteralPart literalPart) if (part is RoutePatternLiteralPart literalPart)
{ {
if (!context.Accept(literalPart.Content)) if (!context.Accept(literalPart.Content))
@ -569,8 +570,10 @@ namespace Microsoft.AspNetCore.Routing.Template
// for format, so we remove '.' and generate 5. // for format, so we remove '.' and generate 5.
if (!context.Accept(converted, parameterPart.EncodeSlashes)) if (!context.Accept(converted, parameterPart.EncodeSlashes))
{ {
if (j != 0 && parameterPart.IsOptional && (separatorPart = parts[j - 1] as RoutePatternSeparatorPart) != null) RoutePatternSeparatorPart? nullablePart;
if (j != 0 && parameterPart.IsOptional && (nullablePart = parts[j - 1] as RoutePatternSeparatorPart) != null)
{ {
separatorPart = nullablePart;
context.Remove(separatorPart.Content); context.Remove(separatorPart.Content);
} }
else else
@ -612,7 +615,7 @@ namespace Microsoft.AspNetCore.Routing.Template
return true; return true;
} }
private bool AddQueryKeyValueToContext(UriBuildingContext context, string key, object value, bool wroteFirst) private bool AddQueryKeyValueToContext(UriBuildingContext context, string key, object? value, bool wroteFirst)
{ {
var converted = Convert.ToString(value, CultureInfo.InvariantCulture); var converted = Convert.ToString(value, CultureInfo.InvariantCulture);
if (!string.IsNullOrEmpty(converted)) if (!string.IsNullOrEmpty(converted))
@ -638,7 +641,7 @@ namespace Microsoft.AspNetCore.Routing.Template
/// <param name="a">An object to compare.</param> /// <param name="a">An object to compare.</param>
/// <param name="b">An object to compare.</param> /// <param name="b">An object to compare.</param>
/// <returns>True if the object are equal, otherwise false.</returns> /// <returns>True if the object are equal, otherwise false.</returns>
public static bool RoutePartsEqual(object a, object b) public static bool RoutePartsEqual(object? a, object? b)
{ {
var sa = a as string ?? (ReferenceEquals(SentinullValue.Instance, a) ? string.Empty : null); var sa = a as string ?? (ReferenceEquals(SentinullValue.Instance, a) ? string.Empty : null);
var sb = b as string ?? (ReferenceEquals(SentinullValue.Instance, b) ? string.Empty : null); var sb = b as string ?? (ReferenceEquals(SentinullValue.Instance, b) ? string.Empty : null);
@ -670,7 +673,7 @@ namespace Microsoft.AspNetCore.Routing.Template
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsRoutePartNonEmpty(object part) private static bool IsRoutePartNonEmpty(object? part)
{ {
if (part == null) if (part == null)
{ {
@ -691,7 +694,7 @@ namespace Microsoft.AspNetCore.Routing.Template
} }
private void CopyNonParameterAmbientValues( private void CopyNonParameterAmbientValues(
RouteValueDictionary ambientValues, RouteValueDictionary? ambientValues,
RouteValueDictionary acceptedValues, RouteValueDictionary acceptedValues,
RouteValueDictionary combinedValues) RouteValueDictionary combinedValues)
{ {
@ -713,18 +716,18 @@ namespace Microsoft.AspNetCore.Routing.Template
} }
} }
private static KeyValuePair<string, object>[] AssignSlots(RoutePattern pattern, KeyValuePair<string, object>[] filters) private static KeyValuePair<string, object?>[] AssignSlots(RoutePattern pattern, KeyValuePair<string, object?>[] filters)
{ {
var slots = new KeyValuePair<string, object>[pattern.Parameters.Count + filters.Length]; var slots = new KeyValuePair<string, object?>[pattern.Parameters.Count + filters.Length];
for (var i = 0; i < pattern.Parameters.Count; i++) for (var i = 0; i < pattern.Parameters.Count; i++)
{ {
slots[i] = new KeyValuePair<string, object>(pattern.Parameters[i].Name, null); slots[i] = new KeyValuePair<string, object?>(pattern.Parameters[i].Name, null);
} }
for (var i = 0; i < filters.Length; i++) for (var i = 0; i < filters.Length; i++)
{ {
slots[i + pattern.Parameters.Count] = new KeyValuePair<string, object>(filters[i].Key, null); slots[i + pattern.Parameters.Count] = new KeyValuePair<string, object?>(filters[i].Key, null);
} }
return slots; return slots;

View File

@ -1,6 +1,8 @@
// 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. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System; using System;
using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
@ -14,7 +16,7 @@ namespace Microsoft.AspNetCore.Routing.Template
// Perf: This is a cache to avoid looking things up in 'Defaults' each request. // Perf: This is a cache to avoid looking things up in 'Defaults' each request.
private readonly bool[] _hasDefaultValue; private readonly bool[] _hasDefaultValue;
private readonly object[] _defaultValues; private readonly object?[] _defaultValues;
private static readonly char[] Delimiters = new char[] { SeparatorChar }; private static readonly char[] Delimiters = new char[] { SeparatorChar };
private RoutePatternMatcher _routePatternMatcher; private RoutePatternMatcher _routePatternMatcher;

View File

@ -54,12 +54,12 @@ namespace Microsoft.AspNetCore.Routing
public TextWriter QueryWriter { get; } public TextWriter QueryWriter { get; }
public bool Accept(string value) public bool Accept(string? value)
{ {
return Accept(value, encodeSlashes: true); return Accept(value, encodeSlashes: true);
} }
public bool Accept(string value, bool encodeSlashes) public bool Accept(string? value, bool encodeSlashes)
{ {
if (string.IsNullOrEmpty(value)) if (string.IsNullOrEmpty(value))
{ {
@ -141,7 +141,7 @@ namespace Microsoft.AspNetCore.Routing
_lastValueOffset = -1; _lastValueOffset = -1;
} }
public bool Buffer(string value) public bool Buffer(string? value)
{ {
if (string.IsNullOrEmpty(value)) if (string.IsNullOrEmpty(value))
{ {