From 8750cd10386e89b46a1b5811170bd4bb21ebb081 Mon Sep 17 00:00:00 2001 From: Pranav K Date: Mon, 6 Jul 2020 20:24:20 -0700 Subject: [PATCH] Nullable followup for Routing (#23474) * Nullable followup for routing. * Update nullability based on usage * Use nullable enable in a few files * More nullable --- .../src/Routing/RouteValueDictionary.cs | 2 +- ...NetCore.Routing.Abstractions.netcoreapp.cs | 20 +++--- .../src/IOutboundParameterTransformer.cs | 4 +- .../src/IRouteConstraint.cs | 2 +- src/Http/Routing.Abstractions/src/IRouter.cs | 2 +- .../src/IRoutingFeature.cs | 4 +- .../Routing.Abstractions/src/LinkGenerator.cs | 20 +++--- .../Routing.Abstractions/src/RouteData.cs | 39 ++++++----- .../src/RoutingHttpContextExtensions.cs | 2 + ...Microsoft.AspNetCore.Routing.netcoreapp.cs | 70 +++++++++---------- .../src/DefaultInlineConstraintResolver.cs | 4 +- src/Http/Routing/src/DefaultLinkGenerator.cs | 49 ++++++------- .../Routing/src/IInlineConstraintResolver.cs | 4 +- src/Http/Routing/src/INamedRouter.cs | 4 +- src/Http/Routing/src/IRouteBuilder.cs | 4 +- .../src/MapRouteRouteBuilderExtensions.cs | 34 ++++----- .../src/Matching/EndpointMetadataComparer.cs | 24 ++++--- .../src/Microsoft.AspNetCore.Routing.csproj | 5 +- .../Routing/src/ParameterPolicyFactory.cs | 4 +- src/Http/Routing/src/Resources.resx | 3 + src/Http/Routing/src/Route.cs | 20 +++--- src/Http/Routing/src/RouteBase.cs | 42 +++++++---- src/Http/Routing/src/RouteBuilder.cs | 6 +- src/Http/Routing/src/RouteCollection.cs | 17 +++-- src/Http/Routing/src/RouteHandler.cs | 4 +- src/Http/Routing/src/RouteValuesAddress.cs | 10 +-- src/Http/Routing/src/RoutingFeature.cs | 2 +- .../Routing/src/Template/RoutePrecedence.cs | 2 + .../Routing/src/Template/RouteTemplate.cs | 6 +- .../Routing/src/Template/TemplateBinder.cs | 59 ++++++++-------- .../Routing/src/Template/TemplateMatcher.cs | 4 +- src/Http/Routing/src/UriBuildingContext.cs | 6 +- 32 files changed, 267 insertions(+), 211 deletions(-) diff --git a/src/Http/Http.Abstractions/src/Routing/RouteValueDictionary.cs b/src/Http/Http.Abstractions/src/Routing/RouteValueDictionary.cs index 815a5d6f10..4f95693da9 100644 --- a/src/Http/Http.Abstractions/src/Routing/RouteValueDictionary.cs +++ b/src/Http/Http.Abstractions/src/Routing/RouteValueDictionary.cs @@ -512,7 +512,7 @@ namespace Microsoft.AspNetCore.Routing 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) { diff --git a/src/Http/Routing.Abstractions/ref/Microsoft.AspNetCore.Routing.Abstractions.netcoreapp.cs b/src/Http/Routing.Abstractions/ref/Microsoft.AspNetCore.Routing.Abstractions.netcoreapp.cs index 12862c2b4d..bfe7f90e3d 100644 --- a/src/Http/Routing.Abstractions/ref/Microsoft.AspNetCore.Routing.Abstractions.netcoreapp.cs +++ b/src/Http/Routing.Abstractions/ref/Microsoft.AspNetCore.Routing.Abstractions.netcoreapp.cs @@ -5,14 +5,14 @@ namespace Microsoft.AspNetCore.Routing { public partial interface IOutboundParameterTransformer : Microsoft.AspNetCore.Routing.IParameterPolicy { - string TransformOutbound(object value); + string? TransformOutbound(object? value); } public partial interface 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 { @@ -20,20 +20,20 @@ namespace Microsoft.AspNetCore.Routing } 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); } public partial interface IRoutingFeature { - Microsoft.AspNetCore.Routing.RouteData RouteData { get; set; } + Microsoft.AspNetCore.Routing.RouteData? RouteData { get; set; } } public abstract partial class LinkGenerator { protected LinkGenerator() { } - public abstract string GetPathByAddress(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 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(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 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? GetPathByAddress(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 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(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 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 { @@ -57,13 +57,13 @@ namespace Microsoft.AspNetCore.Routing public Microsoft.AspNetCore.Routing.RouteValueDictionary DataTokens { get { throw null; } } public System.Collections.Generic.IList Routers { 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)] public readonly partial struct RouteDataSnapshot { private readonly object _dummy; private readonly int _dummyPrimitive; - public RouteDataSnapshot(Microsoft.AspNetCore.Routing.RouteData routeData, Microsoft.AspNetCore.Routing.RouteValueDictionary dataTokens, System.Collections.Generic.IList routers, Microsoft.AspNetCore.Routing.RouteValueDictionary values) { throw null; } + public RouteDataSnapshot(Microsoft.AspNetCore.Routing.RouteData routeData, Microsoft.AspNetCore.Routing.RouteValueDictionary? dataTokens, System.Collections.Generic.IList? routers, Microsoft.AspNetCore.Routing.RouteValueDictionary? values) { throw null; } public void Restore() { } } } diff --git a/src/Http/Routing.Abstractions/src/IOutboundParameterTransformer.cs b/src/Http/Routing.Abstractions/src/IOutboundParameterTransformer.cs index bcc9e21c4d..057528abac 100644 --- a/src/Http/Routing.Abstractions/src/IOutboundParameterTransformer.cs +++ b/src/Http/Routing.Abstractions/src/IOutboundParameterTransformer.cs @@ -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. namespace Microsoft.AspNetCore.Routing @@ -14,6 +14,6 @@ namespace Microsoft.AspNetCore.Routing /// /// The route value to transform. /// The transformed value. - string TransformOutbound(object value); + string? TransformOutbound(object? value); } } diff --git a/src/Http/Routing.Abstractions/src/IRouteConstraint.cs b/src/Http/Routing.Abstractions/src/IRouteConstraint.cs index 5b82823e89..076706dcd9 100644 --- a/src/Http/Routing.Abstractions/src/IRouteConstraint.cs +++ b/src/Http/Routing.Abstractions/src/IRouteConstraint.cs @@ -24,7 +24,7 @@ namespace Microsoft.AspNetCore.Routing /// /// true if the URL parameter contains a valid value; otherwise, false. bool Match( - HttpContext httpContext, + HttpContext? httpContext, IRouter route, string routeKey, RouteValueDictionary values, diff --git a/src/Http/Routing.Abstractions/src/IRouter.cs b/src/Http/Routing.Abstractions/src/IRouter.cs index 06a62bc9ba..d16dcba8fe 100644 --- a/src/Http/Routing.Abstractions/src/IRouter.cs +++ b/src/Http/Routing.Abstractions/src/IRouter.cs @@ -9,6 +9,6 @@ namespace Microsoft.AspNetCore.Routing { Task RouteAsync(RouteContext context); - VirtualPathData GetVirtualPath(VirtualPathContext context); + VirtualPathData? GetVirtualPath(VirtualPathContext context); } } diff --git a/src/Http/Routing.Abstractions/src/IRoutingFeature.cs b/src/Http/Routing.Abstractions/src/IRoutingFeature.cs index bf1897c8ee..882199a32d 100644 --- a/src/Http/Routing.Abstractions/src/IRoutingFeature.cs +++ b/src/Http/Routing.Abstractions/src/IRoutingFeature.cs @@ -1,6 +1,8 @@ // 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. +#nullable enable + namespace Microsoft.AspNetCore.Routing { /// @@ -11,6 +13,6 @@ namespace Microsoft.AspNetCore.Routing /// /// Gets or sets the associated with the current request. /// - RouteData RouteData { get; set; } + RouteData? RouteData { get; set; } } } diff --git a/src/Http/Routing.Abstractions/src/LinkGenerator.cs b/src/Http/Routing.Abstractions/src/LinkGenerator.cs index 90a28ea966..45bf7cd1cd 100644 --- a/src/Http/Routing.Abstractions/src/LinkGenerator.cs +++ b/src/Http/Routing.Abstractions/src/LinkGenerator.cs @@ -11,13 +11,13 @@ namespace Microsoft.AspNetCore.Routing /// /// /// 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 RoutePattern is evaluated, until + /// endpoints that match the address. Secondly, each endpoint's RoutePattern is evaluated, until /// 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 methods provided by the 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 /// is through extension methods that perform operations for a specific /// address type. /// @@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.Routing /// The address type. /// The associated with the current request. /// The address value. Used to resolve endpoints. - /// The route values. Used to expand parameters in the route template. Optional. + /// The route values. Used to expand parameters in the route template. /// The values associated with the current request. Optional. /// /// An optional URI path base. Prepended to the path in the resulting URI. If not provided, the value of will be used. @@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Routing /// names from RouteOptions. /// /// A URI with an absolute path, or null. - public abstract string GetPathByAddress( + public abstract string? GetPathByAddress( HttpContext httpContext, TAddress address, RouteValueDictionary values, @@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Routing /// /// The address type. /// The address value. Used to resolve endpoints. - /// The route values. Used to expand parameters in the route template. Optional. + /// The route values. Used to expand parameters in the route template. /// An optional URI path base. Prepended to the path in the resulting URI. /// An optional URI fragment. Appended to the resulting URI. /// @@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Routing /// names from RouteOptions. /// /// A URI with an absolute path, or null. - public abstract string GetPathByAddress( + public abstract string? GetPathByAddress( TAddress address, RouteValueDictionary values, PathString pathBase = default, @@ -76,7 +76,7 @@ namespace Microsoft.AspNetCore.Routing /// The address type. /// The associated with the current request. /// The address value. Used to resolve endpoints. - /// The route values. Used to expand parameters in the route template. Optional. + /// The route values. Used to expand parameters in the route template. /// The values associated with the current request. Optional. /// /// The URI scheme, applied to the resulting URI. Optional. If not provided, the value of will be used. @@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.Routing /// your deployment environment. /// /// - public abstract string GetUriByAddress( + public abstract string? GetUriByAddress( HttpContext httpContext, TAddress address, RouteValueDictionary values, @@ -118,7 +118,7 @@ namespace Microsoft.AspNetCore.Routing /// /// The address type. /// The address value. Used to resolve endpoints. - /// The route values. Used to expand parameters in the route template. Optional. + /// The route values. Used to expand parameters in the route template. /// The URI scheme, 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. /// /// - public abstract string GetUriByAddress( + public abstract string? GetUriByAddress( TAddress address, RouteValueDictionary values, string scheme, diff --git a/src/Http/Routing.Abstractions/src/RouteData.cs b/src/Http/Routing.Abstractions/src/RouteData.cs index d2d0cd8693..ef3febdc46 100644 --- a/src/Http/Routing.Abstractions/src/RouteData.cs +++ b/src/Http/Routing.Abstractions/src/RouteData.cs @@ -1,8 +1,11 @@ // 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. +#nullable enable + using System; using System.Collections.Generic; +using System.Diagnostics; namespace Microsoft.AspNetCore.Routing { @@ -11,9 +14,9 @@ namespace Microsoft.AspNetCore.Routing /// public class RouteData { - private RouteValueDictionary _dataTokens; - private List _routers; - private RouteValueDictionary _values; + private RouteValueDictionary? _dataTokens; + private List? _routers; + private RouteValueDictionary? _values; /// /// Creates a new instance of instance. @@ -138,14 +141,16 @@ namespace Microsoft.AspNetCore.Routing /// will not be changed. /// /// A that captures the current state. - 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 // Array.CopyTo inside the List(IEnumerable) constructor. - List routers = null; + List? routers = null; var count = _routers?.Count; if (count > 0) { + Debug.Assert(_routers != null); + routers = new List(count.Value); for (var i = 0; i < count.Value; i++) { @@ -192,9 +197,9 @@ namespace Microsoft.AspNetCore.Routing public readonly struct RouteDataSnapshot { private readonly RouteData _routeData; - private readonly RouteValueDictionary _dataTokens; - private readonly IList _routers; - private readonly RouteValueDictionary _values; + private readonly RouteValueDictionary? _dataTokens; + private readonly IList? _routers; + private readonly RouteValueDictionary? _values; /// /// Creates a new instance of for . @@ -205,9 +210,9 @@ namespace Microsoft.AspNetCore.Routing /// The route values. public RouteDataSnapshot( RouteData routeData, - RouteValueDictionary dataTokens, - IList routers, - RouteValueDictionary values) + RouteValueDictionary? dataTokens, + IList? routers, + RouteValueDictionary? values) { if (routeData == null) { @@ -231,11 +236,11 @@ namespace Microsoft.AspNetCore.Routing } else if (_dataTokens == null) { - _routeData._dataTokens.Clear(); + _routeData._dataTokens!.Clear(); } else { - _routeData._dataTokens.Clear(); + _routeData._dataTokens!.Clear(); 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 // Array.Clear inside the List.Clear() method. - var routers = _routeData._routers; + var routers = _routeData._routers!; for (var i = routers.Count - 1; i >= 0 ; 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 // that with the minimal number of reads/writes and without calling Clear(). - var routers = _routeData._routers; + var routers = _routeData._routers!; var snapshotRouters = _routers; // 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) { - _routeData._values.Clear(); + _routeData._values!.Clear(); } else { - _routeData._values.Clear(); + _routeData._values!.Clear(); foreach (var kvp in _values) { diff --git a/src/Http/Routing.Abstractions/src/RoutingHttpContextExtensions.cs b/src/Http/Routing.Abstractions/src/RoutingHttpContextExtensions.cs index 89fcf0ad2d..ca5e69c913 100644 --- a/src/Http/Routing.Abstractions/src/RoutingHttpContextExtensions.cs +++ b/src/Http/Routing.Abstractions/src/RoutingHttpContextExtensions.cs @@ -1,6 +1,8 @@ // 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. +#nullable enable + using System; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; diff --git a/src/Http/Routing/ref/Microsoft.AspNetCore.Routing.netcoreapp.cs b/src/Http/Routing/ref/Microsoft.AspNetCore.Routing.netcoreapp.cs index 25c554c639..74fe3e5f51 100644 --- a/src/Http/Routing/ref/Microsoft.AspNetCore.Routing.netcoreapp.cs +++ b/src/Http/Routing/ref/Microsoft.AspNetCore.Routing.netcoreapp.cs @@ -26,10 +26,10 @@ namespace Microsoft.AspNetCore.Builder } 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, 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, object dataTokens) { 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, 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 partial class RouterMiddleware { @@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.Routing public partial class DefaultInlineConstraintResolver : Microsoft.AspNetCore.Routing.IInlineConstraintResolver { public DefaultInlineConstraintResolver(Microsoft.Extensions.Options.IOptions 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 { @@ -137,11 +137,11 @@ namespace Microsoft.AspNetCore.Routing } 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 { - string Name { get; } + string? Name { get; } } public static partial class InlineRouteParameterParser { @@ -150,7 +150,7 @@ namespace Microsoft.AspNetCore.Routing public partial interface IRouteBuilder { Microsoft.AspNetCore.Builder.IApplicationBuilder ApplicationBuilder { get; } - Microsoft.AspNetCore.Routing.IRouter DefaultHandler { get; set; } + Microsoft.AspNetCore.Routing.IRouter? DefaultHandler { get; set; } System.Collections.Generic.IList Routes { get; } System.IServiceProvider ServiceProvider { get; } Microsoft.AspNetCore.Routing.IRouter Build(); @@ -205,7 +205,7 @@ namespace Microsoft.AspNetCore.Routing protected ParameterPolicyFactory() { } 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 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 { @@ -230,35 +230,35 @@ namespace Microsoft.AspNetCore.Routing 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), default(Microsoft.AspNetCore.Routing.RouteValueDictionary)) { } - public Route(Microsoft.AspNetCore.Routing.IRouter target, string routeTemplate, Microsoft.AspNetCore.Routing.RouteValueDictionary defaults, System.Collections.Generic.IDictionary 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), 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 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), default(Microsoft.AspNetCore.Routing.RouteValueDictionary)) { } + public Route(Microsoft.AspNetCore.Routing.IRouter target, string routeTemplate, Microsoft.AspNetCore.Routing.RouteValueDictionary? defaults, System.Collections.Generic.IDictionary? 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), 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? 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), default(Microsoft.AspNetCore.Routing.RouteValueDictionary)) { } public string RouteTemplate { get { 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 RouteBase(string template, string name, Microsoft.AspNetCore.Routing.IInlineConstraintResolver constraintResolver, Microsoft.AspNetCore.Routing.RouteValueDictionary defaults, System.Collections.Generic.IDictionary 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? 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 { } } public virtual System.Collections.Generic.IDictionary 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 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 { } } - protected static System.Collections.Generic.IDictionary GetConstraints(Microsoft.AspNetCore.Routing.IInlineConstraintResolver inlineConstraintResolver, Microsoft.AspNetCore.Routing.Template.RouteTemplate parsedTemplate, System.Collections.Generic.IDictionary constraints) { 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; } + protected static System.Collections.Generic.IDictionary GetConstraints(Microsoft.AspNetCore.Routing.IInlineConstraintResolver inlineConstraintResolver, Microsoft.AspNetCore.Routing.Template.RouteTemplate parsedTemplate, System.Collections.Generic.IDictionary? constraints) { 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; } 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 override string ToString() { throw null; } } public partial class RouteBuilder : Microsoft.AspNetCore.Routing.IRouteBuilder { 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.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 Routes { [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; } @@ -269,7 +269,7 @@ namespace Microsoft.AspNetCore.Routing public int Count { get { throw null; } } public Microsoft.AspNetCore.Routing.IRouter this[int index] { get { throw null; } } 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] 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 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; } } [System.Diagnostics.DebuggerDisplayAttribute("{DebuggerToString(),nq}")] @@ -335,14 +335,14 @@ namespace Microsoft.AspNetCore.Routing public partial class 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 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 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 { @@ -522,15 +522,15 @@ namespace Microsoft.AspNetCore.Routing.Matching public sealed partial class EndpointMetadataComparer : System.Collections.Generic.IComparer { internal EndpointMetadataComparer() { } - int System.Collections.Generic.IComparer.Compare(Microsoft.AspNetCore.Http.Endpoint x, Microsoft.AspNetCore.Http.Endpoint y) { throw null; } + int System.Collections.Generic.IComparer.Compare(Microsoft.AspNetCore.Http.Endpoint? x, Microsoft.AspNetCore.Http.Endpoint? y) { throw null; } } public abstract partial class EndpointMetadataComparer : System.Collections.Generic.IComparer where TMetadata : class { public static readonly Microsoft.AspNetCore.Routing.Matching.EndpointMetadataComparer Default; protected EndpointMetadataComparer() { } - 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 TMetadata GetMetadata(Microsoft.AspNetCore.Http.Endpoint endpoint) { 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 TMetadata? GetMetadata(Microsoft.AspNetCore.Http.Endpoint endpoint) { throw null; } } public abstract partial class EndpointSelector { @@ -734,17 +734,17 @@ namespace Microsoft.AspNetCore.Routing.Template public System.Collections.Generic.IList Parameters { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } } public System.Collections.Generic.IList Segments { [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.TemplateSegment GetSegment(int index) { 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.Patterns.RoutePattern ToRoutePattern() { throw null; } } public partial class TemplateBinder { internal TemplateBinder() { } - 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 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 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 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 abstract partial class TemplateBinderFactory { diff --git a/src/Http/Routing/src/DefaultInlineConstraintResolver.cs b/src/Http/Routing/src/DefaultInlineConstraintResolver.cs index d70825f57b..01588494c1 100644 --- a/src/Http/Routing/src/DefaultInlineConstraintResolver.cs +++ b/src/Http/Routing/src/DefaultInlineConstraintResolver.cs @@ -1,6 +1,8 @@ // 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. +#nullable enable + using System; using System.Collections.Generic; 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. /// In all other cases arguments are split at comma. /// - public virtual IRouteConstraint ResolveConstraint(string inlineConstraint) + public virtual IRouteConstraint? ResolveConstraint(string inlineConstraint) { if (inlineConstraint == null) { diff --git a/src/Http/Routing/src/DefaultLinkGenerator.cs b/src/Http/Routing/src/DefaultLinkGenerator.cs index 4c11b0abc7..2dda332858 100644 --- a/src/Http/Routing/src/DefaultLinkGenerator.cs +++ b/src/Http/Routing/src/DefaultLinkGenerator.cs @@ -1,19 +1,19 @@ // 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. +#nullable enable + using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Text; -using System.Text.Encodings.Web; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Routing.Template; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.ObjectPool; using Microsoft.Extensions.Options; namespace Microsoft.AspNetCore.Routing @@ -68,14 +68,14 @@ namespace Microsoft.AspNetCore.Routing }; } - public override string GetPathByAddress( + public override string? GetPathByAddress( HttpContext httpContext, TAddress address, RouteValueDictionary values, - RouteValueDictionary ambientValues = default, + RouteValueDictionary? ambientValues = default, PathString? pathBase = default, FragmentString fragment = default, - LinkOptions options = null) + LinkOptions? options = null) { if (httpContext == null) { @@ -98,12 +98,12 @@ namespace Microsoft.AspNetCore.Routing options); } - public override string GetPathByAddress( + public override string? GetPathByAddress( TAddress address, RouteValueDictionary values, PathString pathBase = default, FragmentString fragment = default, - LinkOptions options = null) + LinkOptions? options = null) { var endpoints = GetEndpoints(address); if (endpoints.Count == 0) @@ -121,16 +121,16 @@ namespace Microsoft.AspNetCore.Routing options: options); } - public override string GetUriByAddress( + public override string? GetUriByAddress( HttpContext httpContext, TAddress address, RouteValueDictionary values, - RouteValueDictionary ambientValues = default, - string scheme = default, + RouteValueDictionary? ambientValues = default, + string? scheme = default, HostString? host = default, PathString? pathBase = default, FragmentString fragment = default, - LinkOptions options = null) + LinkOptions? options = null) { if (httpContext == null) { @@ -154,14 +154,14 @@ namespace Microsoft.AspNetCore.Routing options); } - public override string GetUriByAddress( + public override string? GetUriByAddress( TAddress address, RouteValueDictionary values, string scheme, HostString host, PathString pathBase = default, FragmentString fragment = default, - LinkOptions options = null) + LinkOptions? options = null) { if (string.IsNullOrEmpty(scheme)) { @@ -207,14 +207,14 @@ namespace Microsoft.AspNetCore.Routing return endpoints; } - private string GetPathByEndpoints( - HttpContext httpContext, + private string? GetPathByEndpoints( + HttpContext? httpContext, List endpoints, RouteValueDictionary values, - RouteValueDictionary ambientValues, + RouteValueDictionary? ambientValues, PathString pathBase, FragmentString fragment, - LinkOptions options) + LinkOptions? options) { for (var i = 0; i < endpoints.Count; i++) { @@ -242,15 +242,15 @@ namespace Microsoft.AspNetCore.Routing } // Also called from DefaultLinkGenerationTemplate - public string GetUriByEndpoints( + public string? GetUriByEndpoints( List endpoints, RouteValueDictionary values, - RouteValueDictionary ambientValues, + RouteValueDictionary? ambientValues, string scheme, HostString host, PathString pathBase, FragmentString fragment, - LinkOptions options) + LinkOptions? options) { for (var i = 0; i < endpoints.Count; i++) { @@ -289,11 +289,11 @@ namespace Microsoft.AspNetCore.Routing // Internal for testing internal bool TryProcessTemplate( - HttpContext httpContext, + HttpContext? httpContext, RouteEndpoint endpoint, RouteValueDictionary values, - RouteValueDictionary ambientValues, - LinkOptions options, + RouteValueDictionary? ambientValues, + LinkOptions? options, out (PathString path, QueryString query) result) { var templateBinder = GetTemplateBinder(endpoint); @@ -325,7 +325,7 @@ namespace Microsoft.AspNetCore.Routing } // Also called from DefaultLinkGenerationTemplate - public static RouteValueDictionary GetAmbientValues(HttpContext httpContext) + public static RouteValueDictionary? GetAmbientValues(HttpContext httpContext) { return httpContext?.Features.Get()?.RouteValues; } @@ -335,6 +335,7 @@ namespace Microsoft.AspNetCore.Routing _cache.Dispose(); } + #nullable disable private static class Log { public static class EventIds diff --git a/src/Http/Routing/src/IInlineConstraintResolver.cs b/src/Http/Routing/src/IInlineConstraintResolver.cs index d4e0fd028f..a0923adef8 100644 --- a/src/Http/Routing/src/IInlineConstraintResolver.cs +++ b/src/Http/Routing/src/IInlineConstraintResolver.cs @@ -13,6 +13,6 @@ namespace Microsoft.AspNetCore.Routing /// /// The inline constraint to resolve. /// The the inline constraint was resolved to. - IRouteConstraint ResolveConstraint(string inlineConstraint); + IRouteConstraint? ResolveConstraint(string inlineConstraint); } -} \ No newline at end of file +} diff --git a/src/Http/Routing/src/INamedRouter.cs b/src/Http/Routing/src/INamedRouter.cs index b04b7d2f56..8b3a6c63a3 100644 --- a/src/Http/Routing/src/INamedRouter.cs +++ b/src/Http/Routing/src/INamedRouter.cs @@ -5,6 +5,6 @@ namespace Microsoft.AspNetCore.Routing { public interface INamedRouter : IRouter { - string Name { get; } + string? Name { get; } } -} \ No newline at end of file +} diff --git a/src/Http/Routing/src/IRouteBuilder.cs b/src/Http/Routing/src/IRouteBuilder.cs index 2969342724..98f3dbb6e2 100644 --- a/src/Http/Routing/src/IRouteBuilder.cs +++ b/src/Http/Routing/src/IRouteBuilder.cs @@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Routing /// Gets or sets the default that is used as a handler if an /// is added to the list of routes but does not specify its own. /// - IRouter DefaultHandler { get; set; } + IRouter? DefaultHandler { get; set; } /// /// Gets the sets the used to resolve services for routes. @@ -39,4 +39,4 @@ namespace Microsoft.AspNetCore.Routing /// IRouter Build(); } -} \ No newline at end of file +} diff --git a/src/Http/Routing/src/MapRouteRouteBuilderExtensions.cs b/src/Http/Routing/src/MapRouteRouteBuilderExtensions.cs index e5cc19aa1d..23f4536b9b 100644 --- a/src/Http/Routing/src/MapRouteRouteBuilderExtensions.cs +++ b/src/Http/Routing/src/MapRouteRouteBuilderExtensions.cs @@ -1,6 +1,8 @@ // 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. +#nullable enable + using System; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing.Constraints; @@ -22,8 +24,8 @@ namespace Microsoft.AspNetCore.Builder /// A reference to this instance after the operation has completed. public static IRouteBuilder MapRoute( this IRouteBuilder routeBuilder, - string name, - string template) + string? name, + string? template) { MapRoute(routeBuilder, name, template, defaults: null); return routeBuilder; @@ -42,9 +44,9 @@ namespace Microsoft.AspNetCore.Builder /// A reference to this instance after the operation has completed. public static IRouteBuilder MapRoute( this IRouteBuilder routeBuilder, - string name, - string template, - object defaults) + string? name, + string? template, + object? defaults) { return MapRoute(routeBuilder, name, template, defaults, constraints: null); } @@ -67,10 +69,10 @@ namespace Microsoft.AspNetCore.Builder /// A reference to this instance after the operation has completed. public static IRouteBuilder MapRoute( this IRouteBuilder routeBuilder, - string name, - string template, - object defaults, - object constraints) + string? name, + string? template, + object? defaults, + object? constraints) { return MapRoute(routeBuilder, name, template, defaults, constraints, dataTokens: null); } @@ -97,11 +99,11 @@ namespace Microsoft.AspNetCore.Builder /// A reference to this instance after the operation has completed. public static IRouteBuilder MapRoute( this IRouteBuilder routeBuilder, - string name, - string template, - object defaults, - object constraints, - object dataTokens) + string? name, + string? template, + object? defaults, + object? constraints, + object? dataTokens) { if (routeBuilder.DefaultHandler == null) { @@ -113,7 +115,7 @@ namespace Microsoft.AspNetCore.Builder name, template, new RouteValueDictionary(defaults), - new RouteValueDictionary(constraints), + new RouteValueDictionary(constraints)!, new RouteValueDictionary(dataTokens), CreateInlineConstraintResolver(routeBuilder.ServiceProvider))); @@ -144,7 +146,7 @@ namespace Microsoft.AspNetCore.Builder _parameterPolicyFactory = parameterPolicyFactory; } - public IRouteConstraint ResolveConstraint(string inlineConstraint) + public IRouteConstraint? ResolveConstraint(string inlineConstraint) { var routeConstraint = _inner.ResolveConstraint(inlineConstraint); if (routeConstraint != null) diff --git a/src/Http/Routing/src/Matching/EndpointMetadataComparer.cs b/src/Http/Routing/src/Matching/EndpointMetadataComparer.cs index cb42890552..823e64f5e2 100644 --- a/src/Http/Routing/src/Matching/EndpointMetadataComparer.cs +++ b/src/Http/Routing/src/Matching/EndpointMetadataComparer.cs @@ -1,6 +1,8 @@ // 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. +#nullable enable + using System; using System.Collections.Generic; using System.Linq; @@ -17,7 +19,7 @@ namespace Microsoft.AspNetCore.Routing.Matching public sealed class EndpointMetadataComparer : IComparer { private IServiceProvider _services; - private IComparer[] _comparers; + private IComparer[]? _comparers; // This type is **INTENDED** for use in MatcherPolicy instances yet is also needs the MatcherPolicy instances. // using IServiceProvider to break the cycle. @@ -48,7 +50,7 @@ namespace Microsoft.AspNetCore.Routing.Matching } } - int IComparer.Compare(Endpoint x, Endpoint y) + int IComparer.Compare(Endpoint? x, Endpoint? y) { if (x == null) { @@ -75,7 +77,7 @@ namespace Microsoft.AspNetCore.Routing.Matching } /// - /// A base class for implementations that use + /// A base class for implementations that use /// a specific type of metadata from for comparison. /// Useful for implementing . /// @@ -88,17 +90,17 @@ namespace Microsoft.AspNetCore.Routing.Matching public static readonly EndpointMetadataComparer Default = new DefaultComparer(); /// - /// 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. /// /// The first object to compare. /// The second object to compare. /// - /// 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 + /// 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 /// greater than y. /// - public int Compare(Endpoint x, Endpoint y) + public int Compare(Endpoint? x, Endpoint? y) { if (x == null) { @@ -118,7 +120,7 @@ namespace Microsoft.AspNetCore.Routing.Matching /// /// The . /// The instance or null. - protected virtual TMetadata GetMetadata(Endpoint endpoint) + protected virtual TMetadata? GetMetadata(Endpoint endpoint) { return endpoint.Metadata.GetMetadata(); } @@ -129,8 +131,8 @@ namespace Microsoft.AspNetCore.Routing.Matching /// The first object to compare. /// The second object to compare. /// - /// 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 + /// 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 /// greater than y. /// /// @@ -139,7 +141,7 @@ namespace Microsoft.AspNetCore.Routing.Matching /// compared, the endpoint that defines an instance of /// will be considered higher priority. /// - 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 // y endpoint does not, then x is *more specific* than y. We return diff --git a/src/Http/Routing/src/Microsoft.AspNetCore.Routing.csproj b/src/Http/Routing/src/Microsoft.AspNetCore.Routing.csproj index 7652fc21d2..1937aae7f6 100644 --- a/src/Http/Routing/src/Microsoft.AspNetCore.Routing.csproj +++ b/src/Http/Routing/src/Microsoft.AspNetCore.Routing.csproj @@ -1,4 +1,4 @@ - + ASP.NET Core middleware for routing requests to application logic and for generating links. @@ -21,6 +21,7 @@ Microsoft.AspNetCore.Routing.RouteCollection --> false IL_EMIT_SAVE_ASSEMBLIES;$(DefineConstants) + preview @@ -28,7 +29,7 @@ Microsoft.AspNetCore.Routing.RouteCollection - + diff --git a/src/Http/Routing/src/ParameterPolicyFactory.cs b/src/Http/Routing/src/ParameterPolicyFactory.cs index cd875fc907..2d8e665b47 100644 --- a/src/Http/Routing/src/ParameterPolicyFactory.cs +++ b/src/Http/Routing/src/ParameterPolicyFactory.cs @@ -1,4 +1,4 @@ -// Copyright (c) .NET Foundation. All rights reserved. +// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; @@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Routing /// The parameter the parameter policy is being created for. /// The inline text to resolve. /// The for the parameter. - public abstract IParameterPolicy Create(RoutePatternParameterPart parameter, string inlineText); + public abstract IParameterPolicy Create(RoutePatternParameterPart? parameter, string inlineText); /// /// Creates a parameter policy. diff --git a/src/Http/Routing/src/Resources.resx b/src/Http/Routing/src/Resources.resx index 6ce5d8ff00..3bed95c80f 100644 --- a/src/Http/Routing/src/Resources.resx +++ b/src/Http/Routing/src/Resources.resx @@ -231,4 +231,7 @@ The following endpoints with a duplicate endpoint name were found. + + No media type found for format '{0}'. + \ No newline at end of file diff --git a/src/Http/Routing/src/Route.cs b/src/Http/Routing/src/Route.cs index 3d38f922b3..0a6afd3b26 100644 --- a/src/Http/Routing/src/Route.cs +++ b/src/Http/Routing/src/Route.cs @@ -1,6 +1,8 @@ // 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. +#nullable enable + using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -28,9 +30,9 @@ namespace Microsoft.AspNetCore.Routing public Route( IRouter target, string routeTemplate, - RouteValueDictionary defaults, - IDictionary constraints, - RouteValueDictionary dataTokens, + RouteValueDictionary? defaults, + IDictionary? constraints, + RouteValueDictionary? dataTokens, IInlineConstraintResolver inlineConstraintResolver) : this(target, null, routeTemplate, defaults, constraints, dataTokens, inlineConstraintResolver) { @@ -38,11 +40,11 @@ namespace Microsoft.AspNetCore.Routing public Route( IRouter target, - string routeName, - string routeTemplate, - RouteValueDictionary defaults, - IDictionary constraints, - RouteValueDictionary dataTokens, + string? routeName, + string? routeTemplate, + RouteValueDictionary? defaults, + IDictionary? constraints, + RouteValueDictionary? dataTokens, IInlineConstraintResolver inlineConstraintResolver) : base( routeTemplate, @@ -68,7 +70,7 @@ namespace Microsoft.AspNetCore.Routing return _target.RouteAsync(context); } - protected override VirtualPathData OnVirtualPathGenerated(VirtualPathContext context) + protected override VirtualPathData? OnVirtualPathGenerated(VirtualPathContext context) { return _target.GetVirtualPath(context); } diff --git a/src/Http/Routing/src/RouteBase.cs b/src/Http/Routing/src/RouteBase.cs index 019b7a7f7f..2ba62fbcab 100644 --- a/src/Http/Routing/src/RouteBase.cs +++ b/src/Http/Routing/src/RouteBase.cs @@ -1,8 +1,12 @@ // 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. +#nullable enable + using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing.Logging; @@ -16,18 +20,18 @@ namespace Microsoft.AspNetCore.Routing { private readonly object _loggersLock = new object(); - private TemplateMatcher _matcher; - private TemplateBinder _binder; - private ILogger _logger; - private ILogger _constraintLogger; + private TemplateMatcher? _matcher; + private TemplateBinder? _binder; + private ILogger? _logger; + private ILogger? _constraintLogger; public RouteBase( - string template, - string name, + string? template, + string? name, IInlineConstraintResolver constraintResolver, - RouteValueDictionary defaults, - IDictionary constraints, - RouteValueDictionary dataTokens) + RouteValueDictionary? defaults, + IDictionary? constraints, + RouteValueDictionary? dataTokens) { if (constraintResolver == null) { @@ -62,13 +66,13 @@ namespace Microsoft.AspNetCore.Routing 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; } protected abstract Task OnRouteMatched(RouteContext context); - protected abstract VirtualPathData OnVirtualPathGenerated(VirtualPathContext context); + protected abstract VirtualPathData? OnVirtualPathGenerated(VirtualPathContext context); /// public virtual Task RouteAsync(RouteContext context) @@ -106,13 +110,13 @@ namespace Microsoft.AspNetCore.Routing { return Task.CompletedTask; } - _logger.RequestMatchedRoute(Name, ParsedTemplate.TemplateText); + _logger.RequestMatchedRoute(Name!, ParsedTemplate.TemplateText); return OnRouteMatched(context); } /// - public virtual VirtualPathData GetVirtualPath(VirtualPathContext context) + public virtual VirtualPathData? GetVirtualPath(VirtualPathContext context) { EnsureBinder(context.HttpContext); EnsureLoggers(context.HttpContext); @@ -169,7 +173,7 @@ namespace Microsoft.AspNetCore.Routing protected static IDictionary GetConstraints( IInlineConstraintResolver inlineConstraintResolver, RouteTemplate parsedTemplate, - IDictionary constraints) + IDictionary? constraints) { var constraintBuilder = new RouteConstraintBuilder(inlineConstraintResolver, parsedTemplate.TemplateText); @@ -199,7 +203,7 @@ namespace Microsoft.AspNetCore.Routing protected static RouteValueDictionary GetDefaults( RouteTemplate parsedTemplate, - RouteValueDictionary defaults) + 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) { if (_binder == null) @@ -254,6 +259,7 @@ namespace Microsoft.AspNetCore.Routing } } + [MemberNotNull(nameof(_logger), nameof(_constraintLogger))] private void EnsureLoggers(HttpContext context) { // 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 // there is nothing wrong if things get reinitialized by a second thread, but its easy // to prevent by just rechecking and returning here. + Debug.Assert(_constraintLogger != null); + return; } @@ -275,9 +283,13 @@ namespace Microsoft.AspNetCore.Routing _constraintLogger = factory.CreateLogger(typeof(RouteConstraintMatcher).FullName); _logger = factory.CreateLogger(typeof(RouteBase).FullName); } + } + + Debug.Assert(_constraintLogger != null); } + [MemberNotNull(nameof(_matcher))] private void EnsureMatcher() { if (_matcher == null) diff --git a/src/Http/Routing/src/RouteBuilder.cs b/src/Http/Routing/src/RouteBuilder.cs index 8899aa6e9a..e6673ac5b7 100644 --- a/src/Http/Routing/src/RouteBuilder.cs +++ b/src/Http/Routing/src/RouteBuilder.cs @@ -1,6 +1,8 @@ // 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. +#nullable enable + using System; using System.Collections.Generic; 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) { @@ -39,7 +41,7 @@ namespace Microsoft.AspNetCore.Routing public IApplicationBuilder ApplicationBuilder { get; } - public IRouter DefaultHandler { get; set; } + public IRouter? DefaultHandler { get; set; } public IServiceProvider ServiceProvider { get; } diff --git a/src/Http/Routing/src/RouteCollection.cs b/src/Http/Routing/src/RouteCollection.cs index 555fdd63ae..ac499f4f5e 100644 --- a/src/Http/Routing/src/RouteCollection.cs +++ b/src/Http/Routing/src/RouteCollection.cs @@ -1,8 +1,12 @@ // 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. +#nullable enable + using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; @@ -18,7 +22,7 @@ namespace Microsoft.AspNetCore.Routing private readonly Dictionary _namedRoutes = new Dictionary(StringComparer.OrdinalIgnoreCase); - private RouteOptions _options; + private RouteOptions? _options; 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); if (!string.IsNullOrEmpty(context.RouteName)) { - VirtualPathData namedRoutePathData = null; + VirtualPathData? namedRoutePathData = null; if (_namedRoutes.TryGetValue(context.RouteName, out var matchedNamedRoute)) { @@ -114,7 +118,7 @@ namespace Microsoft.AspNetCore.Routing } } - private VirtualPathData GetVirtualPath(VirtualPathContext context, List routes) + private VirtualPathData? GetVirtualPath(VirtualPathContext context, List routes) { for (var i = 0; i < routes.Count; i++) { @@ -130,13 +134,15 @@ namespace Microsoft.AspNetCore.Routing return null; } - private VirtualPathData NormalizeVirtualPath(VirtualPathData pathData) + private VirtualPathData? NormalizeVirtualPath(VirtualPathData? pathData) { if (pathData == null) { return pathData; } + Debug.Assert(_options != null); + var url = pathData.VirtualPath; if (!string.IsNullOrEmpty(url) && (_options.LowercaseUrls || _options.AppendTrailingSlash)) @@ -175,6 +181,7 @@ namespace Microsoft.AspNetCore.Routing return pathData; } + [MemberNotNull(nameof(_options))] private void EnsureOptions(HttpContext context) { if (_options == null) diff --git a/src/Http/Routing/src/RouteHandler.cs b/src/Http/Routing/src/RouteHandler.cs index a2fcce601f..197e28794d 100644 --- a/src/Http/Routing/src/RouteHandler.cs +++ b/src/Http/Routing/src/RouteHandler.cs @@ -1,6 +1,8 @@ // 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. +#nullable enable + using System.Threading.Tasks; using Microsoft.AspNetCore.Http; @@ -20,7 +22,7 @@ namespace Microsoft.AspNetCore.Routing return _requestDelegate; } - public VirtualPathData GetVirtualPath(VirtualPathContext context) + public VirtualPathData? GetVirtualPath(VirtualPathContext context) { // Nothing to do. return null; diff --git a/src/Http/Routing/src/RouteValuesAddress.cs b/src/Http/Routing/src/RouteValuesAddress.cs index eec1660854..b628d06841 100644 --- a/src/Http/Routing/src/RouteValuesAddress.cs +++ b/src/Http/Routing/src/RouteValuesAddress.cs @@ -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. +#nullable enable + namespace Microsoft.AspNetCore.Routing { /// @@ -11,16 +13,16 @@ namespace Microsoft.AspNetCore.Routing /// /// Gets or sets the route name. /// - public string RouteName { get; set; } + public string? RouteName { get; set; } /// /// Gets or sets the route values that are explicitly specified. /// - public RouteValueDictionary ExplicitValues { get; set; } + public RouteValueDictionary ExplicitValues { get; set; } = default!; /// /// Gets or sets ambient route values from the current HTTP request. /// - public RouteValueDictionary AmbientValues { get; set; } + public RouteValueDictionary? AmbientValues { get; set; } } } diff --git a/src/Http/Routing/src/RoutingFeature.cs b/src/Http/Routing/src/RoutingFeature.cs index 30b88ac1b9..f3d9503df5 100644 --- a/src/Http/Routing/src/RoutingFeature.cs +++ b/src/Http/Routing/src/RoutingFeature.cs @@ -5,6 +5,6 @@ namespace Microsoft.AspNetCore.Routing { public class RoutingFeature : IRoutingFeature { - public RouteData RouteData { get; set; } + public RouteData? RouteData { get; set; } } } diff --git a/src/Http/Routing/src/Template/RoutePrecedence.cs b/src/Http/Routing/src/Template/RoutePrecedence.cs index 3bad48614b..eea1057285 100644 --- a/src/Http/Routing/src/Template/RoutePrecedence.cs +++ b/src/Http/Routing/src/Template/RoutePrecedence.cs @@ -1,6 +1,8 @@ // 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. +#nullable enable + using System; using System.Diagnostics; using System.Linq; diff --git a/src/Http/Routing/src/Template/RouteTemplate.cs b/src/Http/Routing/src/Template/RouteTemplate.cs index 027020a02d..ec5d5631f6 100644 --- a/src/Http/Routing/src/Template/RouteTemplate.cs +++ b/src/Http/Routing/src/Template/RouteTemplate.cs @@ -1,6 +1,8 @@ // 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. +#nullable enable + using System; using System.Collections.Generic; using System.Diagnostics; @@ -72,7 +74,7 @@ namespace Microsoft.AspNetCore.Routing.Template public IList Segments { get; } - public TemplateSegment GetSegment(int index) + public TemplateSegment? GetSegment(int index) { if (index < 0) { @@ -92,7 +94,7 @@ namespace Microsoft.AspNetCore.Routing.Template /// /// The name of the parameter to match. /// The matching parameter or null if no parameter matches the given name. - public TemplatePart GetParameter(string name) + public TemplatePart? GetParameter(string name) { for (var i = 0; i < Parameters.Count; i++) { diff --git a/src/Http/Routing/src/Template/TemplateBinder.cs b/src/Http/Routing/src/Template/TemplateBinder.cs index 1d3cbd6dcc..10af79ec2c 100644 --- a/src/Http/Routing/src/Template/TemplateBinder.cs +++ b/src/Http/Routing/src/Template/TemplateBinder.cs @@ -1,6 +1,8 @@ // 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. +#nullable enable + using System; using System.Collections; using System.Collections.Generic; @@ -21,8 +23,8 @@ namespace Microsoft.AspNetCore.Routing.Template private readonly ObjectPool _pool; private readonly (string parameterName, IRouteConstraint constraint)[] _constraints; - private readonly RouteValueDictionary _defaults; - private readonly KeyValuePair[] _filters; + private readonly RouteValueDictionary? _defaults; + private readonly KeyValuePair[] _filters; private readonly (string parameterName, IOutboundParameterTransformer transformer)[] _parameterTransformers; private readonly RoutePattern _pattern; 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. // // We always make a copy of this and operate on the copy, so that we don't mutate shared state. - private readonly KeyValuePair[] _slots; + private readonly KeyValuePair[] _slots; /// /// Creates a new instance of . @@ -44,7 +46,7 @@ namespace Microsoft.AspNetCore.Routing.Template ObjectPool pool, RouteTemplate template, 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, ObjectPool pool, RoutePattern pattern, - RouteValueDictionary defaults, - IEnumerable requiredKeys, - IEnumerable<(string parameterName, IParameterPolicy policy)> parameterPolicies) + RouteValueDictionary? defaults, + IEnumerable? requiredKeys, + IEnumerable<(string parameterName, IParameterPolicy policy)>? parameterPolicies) { 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 - 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 // and then the RVD will take ownership of it. - var slots = new KeyValuePair[_slots.Length]; + var slots = new KeyValuePair[_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 @@ -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 // null means omitted. value = IsRoutePartNonEmpty(value) ? value : SentinullValue.Instance; - slots[i] = new KeyValuePair(key, value); + slots[i] = new KeyValuePair(key, value); // Track the count of processed values - this allows a fast path later. valueProcessedCount++; @@ -266,7 +268,7 @@ namespace Microsoft.AspNetCore.Routing.Template var hasExplicitValue = value != null; var hasAmbientValue = false; - var ambientValue = (object)null; + var ambientValue = (object?)null; var parameter = parameters[i]; @@ -318,7 +320,7 @@ namespace Microsoft.AspNetCore.Routing.Template (RoutePartsEqual(requiredValue, ambientValue) || RoutePattern.IsRequiredValueAny(requiredValue))) { // Treat this an an explicit value to *force it*. - slots[i] = new KeyValuePair(key, ambientValue); + slots[i] = new KeyValuePair(key, ambientValue); hasExplicitValue = true; value = ambientValue; } @@ -331,7 +333,7 @@ namespace Microsoft.AspNetCore.Routing.Template } else if (copyAmbientValues && hasAmbientValue) { - slots[i] = new KeyValuePair(key, ambientValue); + slots[i] = new KeyValuePair(key, ambientValue); } 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 // only if it actually has a default value. - slots[i] = new KeyValuePair(key, defaultValue); + slots[i] = new KeyValuePair(key, defaultValue); } else { @@ -392,7 +394,7 @@ namespace Microsoft.AspNetCore.Routing.Template // the dictionary. foreach (var kvp in values) { - if (!_defaults.ContainsKey(kvp.Key)) + if (!_defaults!.ContainsKey(kvp.Key)) { #if RVD_TryAdd 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. // Returns true on success // 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; 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 - public string BindValues(RouteValueDictionary acceptedValues) + public string? BindValues(RouteValueDictionary acceptedValues) { 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 internal bool TryBindValues( RouteValueDictionary acceptedValues, - LinkOptions options, + LinkOptions? options, LinkOptions globalOptions, out (PathString path, QueryString query) result) { @@ -519,7 +521,6 @@ namespace Microsoft.AspNetCore.Routing.Template for (var j = 0; j < partsCount; j++) { var part = parts[j]; - if (part is RoutePatternLiteralPart literalPart) { if (!context.Accept(literalPart.Content)) @@ -569,8 +570,10 @@ namespace Microsoft.AspNetCore.Routing.Template // for format, so we remove '.' and generate 5. 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); } else @@ -612,7 +615,7 @@ namespace Microsoft.AspNetCore.Routing.Template 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); if (!string.IsNullOrEmpty(converted)) @@ -638,7 +641,7 @@ namespace Microsoft.AspNetCore.Routing.Template /// An object to compare. /// An object to compare. /// True if the object are equal, otherwise false. - 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 sb = b as string ?? (ReferenceEquals(SentinullValue.Instance, b) ? string.Empty : null); @@ -670,7 +673,7 @@ namespace Microsoft.AspNetCore.Routing.Template } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static bool IsRoutePartNonEmpty(object part) + private static bool IsRoutePartNonEmpty(object? part) { if (part == null) { @@ -691,7 +694,7 @@ namespace Microsoft.AspNetCore.Routing.Template } private void CopyNonParameterAmbientValues( - RouteValueDictionary ambientValues, + RouteValueDictionary? ambientValues, RouteValueDictionary acceptedValues, RouteValueDictionary combinedValues) { @@ -713,18 +716,18 @@ namespace Microsoft.AspNetCore.Routing.Template } } - private static KeyValuePair[] AssignSlots(RoutePattern pattern, KeyValuePair[] filters) + private static KeyValuePair[] AssignSlots(RoutePattern pattern, KeyValuePair[] filters) { - var slots = new KeyValuePair[pattern.Parameters.Count + filters.Length]; + var slots = new KeyValuePair[pattern.Parameters.Count + filters.Length]; for (var i = 0; i < pattern.Parameters.Count; i++) { - slots[i] = new KeyValuePair(pattern.Parameters[i].Name, null); + slots[i] = new KeyValuePair(pattern.Parameters[i].Name, null); } for (var i = 0; i < filters.Length; i++) { - slots[i + pattern.Parameters.Count] = new KeyValuePair(filters[i].Key, null); + slots[i + pattern.Parameters.Count] = new KeyValuePair(filters[i].Key, null); } return slots; diff --git a/src/Http/Routing/src/Template/TemplateMatcher.cs b/src/Http/Routing/src/Template/TemplateMatcher.cs index 31bb97d394..97dc3565dd 100644 --- a/src/Http/Routing/src/Template/TemplateMatcher.cs +++ b/src/Http/Routing/src/Template/TemplateMatcher.cs @@ -1,6 +1,8 @@ // 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. +#nullable enable + using System; using Microsoft.AspNetCore.Routing; 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. private readonly bool[] _hasDefaultValue; - private readonly object[] _defaultValues; + private readonly object?[] _defaultValues; private static readonly char[] Delimiters = new char[] { SeparatorChar }; private RoutePatternMatcher _routePatternMatcher; diff --git a/src/Http/Routing/src/UriBuildingContext.cs b/src/Http/Routing/src/UriBuildingContext.cs index 974bcd8a1e..5bc974d546 100644 --- a/src/Http/Routing/src/UriBuildingContext.cs +++ b/src/Http/Routing/src/UriBuildingContext.cs @@ -54,12 +54,12 @@ namespace Microsoft.AspNetCore.Routing public TextWriter QueryWriter { get; } - public bool Accept(string value) + public bool Accept(string? value) { return Accept(value, encodeSlashes: true); } - public bool Accept(string value, bool encodeSlashes) + public bool Accept(string? value, bool encodeSlashes) { if (string.IsNullOrEmpty(value)) { @@ -141,7 +141,7 @@ namespace Microsoft.AspNetCore.Routing _lastValueOffset = -1; } - public bool Buffer(string value) + public bool Buffer(string? value) { if (string.IsNullOrEmpty(value)) {