Turn on nullability for Routing (#24238)

* Turn on nullability for Routing

We previously only had annotations enabled which resulted in incorrect nullability. This change enables
nullability.

Fixes https://github.com/dotnet/aspnetcore/issues/24042
This commit is contained in:
Pranav K 2020-07-25 07:34:05 -07:00 committed by GitHub
parent 64b5ea9393
commit f26942805d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
100 changed files with 344 additions and 287 deletions

View File

@ -20,8 +20,8 @@ namespace Microsoft.AspNetCore.Http
/// </param> /// </param>
public Endpoint( public Endpoint(
RequestDelegate requestDelegate, RequestDelegate requestDelegate,
EndpointMetadataCollection metadata, EndpointMetadataCollection? metadata,
string displayName) string? displayName)
{ {
// All are allowed to be null // All are allowed to be null
RequestDelegate = requestDelegate; RequestDelegate = requestDelegate;
@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Http
/// <summary> /// <summary>
/// Gets the informational display name of this endpoint. /// Gets the informational display name of this endpoint.
/// </summary> /// </summary>
public string DisplayName { get; } public string? DisplayName { get; }
/// <summary> /// <summary>
/// Gets the collection of metadata associated with this endpoint. /// Gets the collection of metadata associated with this endpoint.

View File

@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Routing
/// <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,
RouteDirection routeDirection); RouteDirection routeDirection);

View File

@ -6,6 +6,7 @@
// //
// See https://github.com/dotnet/corefx/blob/143df51926f2ad397fef9c9ca7ede88e2721e801/src/Common/src/System/Collections/Generic/ArrayBuilder.cs // See https://github.com/dotnet/corefx/blob/143df51926f2ad397fef9c9ca7ede88e2721e801/src/Common/src/System/Collections/Generic/ArrayBuilder.cs
#nullable disable
using System; using System;
using System.Diagnostics; using System.Diagnostics;

View File

@ -128,7 +128,7 @@ namespace Microsoft.AspNetCore.Builder
} }
// If someone messes with this, just let it crash. // If someone messes with this, just let it crash.
endpointRouteBuilder = (DefaultEndpointRouteBuilder)obj; endpointRouteBuilder = (DefaultEndpointRouteBuilder)obj!;
// This check handles the case where Map or something else that forks the pipeline is called between the two // This check handles the case where Map or something else that forks the pipeline is called between the two
// routing middleware. // routing middleware.

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;
@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
@ -21,8 +22,8 @@ namespace Microsoft.AspNetCore.Routing
public sealed class CompositeEndpointDataSource : EndpointDataSource public sealed class CompositeEndpointDataSource : EndpointDataSource
{ {
private readonly object _lock; private readonly object _lock;
private readonly ICollection<EndpointDataSource> _dataSources; private readonly ICollection<EndpointDataSource> _dataSources = default!;
private IReadOnlyList<Endpoint> _endpoints; private IReadOnlyList<Endpoint> _endpoints = default!;
private IChangeToken _consumerChangeToken; private IChangeToken _consumerChangeToken;
private CancellationTokenSource _cts; private CancellationTokenSource _cts;
@ -49,7 +50,7 @@ namespace Microsoft.AspNetCore.Routing
} }
} }
private void OnDataSourcesChanged(object sender, NotifyCollectionChangedEventArgs e) private void OnDataSourcesChanged(object? sender, NotifyCollectionChangedEventArgs e)
{ {
lock (_lock) lock (_lock)
{ {
@ -140,6 +141,7 @@ namespace Microsoft.AspNetCore.Routing
} }
} }
[MemberNotNull(nameof(_cts), nameof(_consumerChangeToken))]
private void CreateChangeToken() private void CreateChangeToken()
{ {
_cts = new CancellationTokenSource(); _cts = new CancellationTokenSource();
@ -198,7 +200,7 @@ namespace Microsoft.AspNetCore.Routing
} }
return sb.ToString(); return sb.ToString();
IEnumerable<string> FormatValues(IEnumerable<KeyValuePair<string, object>> values) IEnumerable<string> FormatValues(IEnumerable<KeyValuePair<string, object?>> values)
{ {
return values.Select( return values.Select(
kvp => kvp =>

View File

@ -14,8 +14,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
{ {
/// <inheritdoc /> /// <inheritdoc />
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)

View File

@ -33,8 +33,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
/// <inheritdoc /> /// <inheritdoc />
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)

View File

@ -20,8 +20,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
{ {
/// <inheritdoc /> /// <inheritdoc />
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)

View File

@ -14,8 +14,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
{ {
/// <inheritdoc /> /// <inheritdoc />
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)

View File

@ -14,8 +14,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
{ {
/// <inheritdoc /> /// <inheritdoc />
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)

View File

@ -85,8 +85,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
{ {
/// <inheritdoc /> /// <inheritdoc />
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)

View File

@ -14,8 +14,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
{ {
/// <inheritdoc /> /// <inheritdoc />
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)

View File

@ -16,8 +16,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
{ {
/// <inheritdoc /> /// <inheritdoc />
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)

View File

@ -35,8 +35,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
/// <inheritdoc /> /// <inheritdoc />
public virtual bool Match( public virtual bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)

View File

@ -14,8 +14,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
{ {
/// <inheritdoc /> /// <inheritdoc />
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)

View File

@ -71,8 +71,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
/// <inheritdoc /> /// <inheritdoc />
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)
@ -89,7 +89,7 @@ namespace Microsoft.AspNetCore.Routing.Constraints
if (values.TryGetValue(routeKey, out var value) && value != null) if (values.TryGetValue(routeKey, out var value) && value != null)
{ {
var valueString = Convert.ToString(value, CultureInfo.InvariantCulture); var valueString = Convert.ToString(value, CultureInfo.InvariantCulture)!;
var length = valueString.Length; var length = valueString.Length;
return length >= MinLength && length <= MaxLength; return length >= MinLength && length <= MaxLength;
} }

View File

@ -14,8 +14,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
{ {
/// <inheritdoc /> /// <inheritdoc />
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)

View File

@ -34,8 +34,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
/// <inheritdoc /> /// <inheritdoc />
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)
@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Routing.Constraints
if (values.TryGetValue(routeKey, out var value) && value != null) if (values.TryGetValue(routeKey, out var value) && value != null)
{ {
var valueString = Convert.ToString(value, CultureInfo.InvariantCulture); var valueString = Convert.ToString(value, CultureInfo.InvariantCulture)!;
return valueString.Length <= MaxLength; return valueString.Length <= MaxLength;
} }

View File

@ -28,8 +28,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
/// <inheritdoc /> /// <inheritdoc />
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)

View File

@ -34,8 +34,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
/// <inheritdoc /> /// <inheritdoc />
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)
@ -52,7 +52,7 @@ namespace Microsoft.AspNetCore.Routing.Constraints
if (values.TryGetValue(routeKey, out var value) && value != null) if (values.TryGetValue(routeKey, out var value) && value != null)
{ {
var valueString = Convert.ToString(value, CultureInfo.InvariantCulture); var valueString = Convert.ToString(value, CultureInfo.InvariantCulture)!;
return valueString.Length >= MinLength; return valueString.Length >= MinLength;
} }

View File

@ -28,8 +28,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
/// <inheritdoc /> /// <inheritdoc />
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)

View File

@ -81,8 +81,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
{ {
/// <inheritdoc /> /// <inheritdoc />
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)

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 Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Routing.Constraints
{ {
} }
public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection) public bool Match(HttpContext? httpContext, IRouter? route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
{ {
return true; return true;
} }

View File

@ -24,8 +24,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
public IRouteConstraint InnerConstraint { get; } public IRouteConstraint InnerConstraint { get; }
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)

View File

@ -42,8 +42,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
/// <inheritdoc /> /// <inheritdoc />
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)

View File

@ -38,8 +38,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
public Regex Constraint { get; private set; } public Regex Constraint { get; private set; }
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)
@ -57,7 +57,7 @@ namespace Microsoft.AspNetCore.Routing.Constraints
if (values.TryGetValue(routeKey, out var routeValue) if (values.TryGetValue(routeKey, out var routeValue)
&& routeValue != null) && routeValue != null)
{ {
var parameterValueString = Convert.ToString(routeValue, CultureInfo.InvariantCulture); var parameterValueString = Convert.ToString(routeValue, CultureInfo.InvariantCulture)!;
return Constraint.IsMatch(parameterValueString); return Constraint.IsMatch(parameterValueString);
} }

View File

@ -18,8 +18,8 @@ namespace Microsoft.AspNetCore.Routing.Constraints
{ {
/// <inheritdoc /> /// <inheritdoc />
public bool Match( public bool Match(
HttpContext httpContext, HttpContext? httpContext,
IRouter route, IRouter? route,
string routeKey, string routeKey,
RouteValueDictionary values, RouteValueDictionary values,
RouteDirection routeDirection) RouteDirection routeDirection)

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;
@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Routing.Constraints
} }
/// <inheritdoc /> /// <inheritdoc />
public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection) public bool Match(HttpContext? httpContext, IRouter? route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
{ {
if (routeKey == null) if (routeKey == null)
{ {
@ -44,7 +44,7 @@ namespace Microsoft.AspNetCore.Routing.Constraints
if (values.TryGetValue(routeKey, out var routeValue) if (values.TryGetValue(routeKey, out var routeValue)
&& routeValue != null) && routeValue != null)
{ {
var parameterValueString = Convert.ToString(routeValue, CultureInfo.InvariantCulture); var parameterValueString = Convert.ToString(routeValue, CultureInfo.InvariantCulture)!;
return parameterValueString.Equals(_value, StringComparison.OrdinalIgnoreCase); return parameterValueString.Equals(_value, StringComparison.OrdinalIgnoreCase);
} }

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 disable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading; using System.Threading;

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 disable
using System.Collections.Generic; using System.Collections.Generic;
namespace Microsoft.AspNetCore.Routing.DecisionTree namespace Microsoft.AspNetCore.Routing.DecisionTree

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 disable
using System.Collections.Generic; using System.Collections.Generic;
namespace Microsoft.AspNetCore.Routing.DecisionTree namespace Microsoft.AspNetCore.Routing.DecisionTree

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 disable
using System.Collections.Generic; using System.Collections.Generic;
namespace Microsoft.AspNetCore.Routing.DecisionTree namespace Microsoft.AspNetCore.Routing.DecisionTree

View File

@ -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;
} }

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -46,7 +47,7 @@ namespace Microsoft.AspNetCore.Routing
_createMatcher = CreateRoutePatternMatcher; _createMatcher = CreateRoutePatternMatcher;
} }
public override RouteValueDictionary ParsePathByAddress<TAddress>(TAddress address, PathString path) public override RouteValueDictionary? ParsePathByAddress<TAddress>(TAddress address, PathString path)
{ {
var endpoints = GetEndpoints(address); var endpoints = GetEndpoints(address);
if (endpoints.Count == 0) if (endpoints.Count == 0)
@ -117,7 +118,7 @@ namespace Microsoft.AspNetCore.Routing
internal MatcherState GetMatcherState(RouteEndpoint endpoint) => _matcherCache.EnsureInitialized().GetOrAdd(endpoint, _createMatcher); internal MatcherState GetMatcherState(RouteEndpoint endpoint) => _matcherCache.EnsureInitialized().GetOrAdd(endpoint, _createMatcher);
// Internal for testing // Internal for testing
internal bool TryParse(RouteEndpoint endpoint, PathString path, out RouteValueDictionary values) internal bool TryParse(RouteEndpoint endpoint, PathString path, [NotNullWhen(true)] out RouteValueDictionary? values)
{ {
var (matcher, constraints) = GetMatcherState(endpoint); var (matcher, constraints) = GetMatcherState(endpoint);
@ -168,6 +169,7 @@ namespace Microsoft.AspNetCore.Routing
} }
} }
#nullable disable
private static class Log private static class Log
{ {
public static class EventIds public static class EventIds

View File

@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Routing
_serviceProvider = serviceProvider; _serviceProvider = serviceProvider;
} }
public override IParameterPolicy Create(RoutePatternParameterPart parameter, IParameterPolicy parameterPolicy) public override IParameterPolicy Create(RoutePatternParameterPart? parameter, IParameterPolicy parameterPolicy)
{ {
if (parameterPolicy == null) if (parameterPolicy == null)
{ {
@ -36,7 +36,7 @@ namespace Microsoft.AspNetCore.Routing
return parameterPolicy; return parameterPolicy;
} }
public override IParameterPolicy Create(RoutePatternParameterPart parameter, string inlineText) public override IParameterPolicy Create(RoutePatternParameterPart? parameter, string inlineText)
{ {
if (inlineText == null) if (inlineText == null)
{ {

View File

@ -101,6 +101,7 @@ namespace Microsoft.AspNetCore.Routing
"Configure your application startup by adding app.UseCors() inside the call to Configure(..) in the application startup code. The call to app.UseCors() must appear between app.UseRouting() and app.UseEndpoints(...)."); "Configure your application startup by adding app.UseCors() inside the call to Configure(..) in the application startup code. The call to app.UseCors() must appear between app.UseRouting() and app.UseEndpoints(...).");
} }
#nullable disable
private static class Log private static class Log
{ {
private static readonly Action<ILogger, string, Exception> _executingEndpoint = LoggerMessage.Define<string>( private static readonly Action<ILogger, string, Exception> _executingEndpoint = LoggerMessage.Define<string>(

View File

@ -92,7 +92,7 @@ namespace Microsoft.AspNetCore.Routing
throw new InvalidOperationException(builder.ToString()); throw new InvalidOperationException(builder.ToString());
string GetEndpointName(Endpoint endpoint) string? GetEndpointName(Endpoint endpoint)
{ {
if (endpoint.Metadata.GetMetadata<ISuppressLinkGenerationMetadata>()?.SuppressLinkGeneration == true) if (endpoint.Metadata.GetMetadata<ISuppressLinkGenerationMetadata>()?.SuppressLinkGeneration == true)
{ {

View File

@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Routing
private readonly DiagnosticListener _diagnosticListener; private readonly DiagnosticListener _diagnosticListener;
private readonly RequestDelegate _next; private readonly RequestDelegate _next;
private Task<Matcher> _initializationTask; private Task<Matcher>? _initializationTask;
public EndpointRoutingMiddleware( public EndpointRoutingMiddleware(
MatcherFactory matcherFactory, MatcherFactory matcherFactory,
@ -165,6 +165,7 @@ namespace Microsoft.AspNetCore.Routing
} }
} }
#nullable disable
private static class Log private static class Log
{ {
private static readonly Action<ILogger, string, Exception> _matchSuccess = LoggerMessage.Define<string>( private static readonly Action<ILogger, string, Exception> _matchSuccess = LoggerMessage.Define<string>(

View File

@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.Routing
var parseResults = ParseConstraints(routeParameter, currentIndex, endIndex); var parseResults = ParseConstraints(routeParameter, currentIndex, endIndex);
currentIndex = parseResults.CurrentIndex; currentIndex = parseResults.CurrentIndex;
string defaultValue = null; string? defaultValue = null;
if (currentIndex <= endIndex && if (currentIndex <= endIndex &&
routeParameter[currentIndex] == '=') routeParameter[currentIndex] == '=')
{ {

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 Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
@ -27,14 +27,14 @@ 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 static string GetPathByName( public static string? GetPathByName(
this LinkGenerator generator, this LinkGenerator generator,
HttpContext httpContext, HttpContext httpContext,
string endpointName, string endpointName,
object values, object? values,
PathString? pathBase = default, PathString? pathBase = default,
FragmentString fragment = default, FragmentString fragment = default,
LinkOptions options = default) LinkOptions? options = default)
{ {
if (generator == null) if (generator == null)
{ {
@ -74,13 +74,13 @@ 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 static string GetPathByName( public static string? GetPathByName(
this LinkGenerator generator, this LinkGenerator generator,
string endpointName, string endpointName,
object values, object? values,
PathString pathBase = default, PathString pathBase = default,
FragmentString fragment = default, FragmentString fragment = default,
LinkOptions options = default) LinkOptions? options = default)
{ {
if (generator == null) if (generator == null)
{ {
@ -126,16 +126,16 @@ namespace Microsoft.AspNetCore.Routing
/// your deployment environment. /// your deployment environment.
/// </para> /// </para>
/// </remarks> /// </remarks>
public static string GetUriByName( public static string? GetUriByName(
this LinkGenerator generator, this LinkGenerator generator,
HttpContext httpContext, HttpContext httpContext,
string endpointName, string endpointName,
object values, object? values,
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 = default) LinkOptions? options = default)
{ {
if (generator == null) if (generator == null)
{ {
@ -190,15 +190,15 @@ namespace Microsoft.AspNetCore.Routing
/// your deployment environment. /// your deployment environment.
/// </para> /// </para>
/// </remarks> /// </remarks>
public static string GetUriByName( public static string? GetUriByName(
this LinkGenerator generator, this LinkGenerator generator,
string endpointName, string endpointName,
object values, object? values,
string scheme, string scheme,
HostString host, HostString host,
PathString pathBase = default, PathString pathBase = default,
FragmentString fragment = default, FragmentString fragment = default,
LinkOptions options = default) LinkOptions? options = default)
{ {
if (generator == null) if (generator == null)
{ {

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 Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
@ -27,14 +27,14 @@ 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 static string GetPathByRouteValues( public static string? GetPathByRouteValues(
this LinkGenerator generator, this LinkGenerator generator,
HttpContext httpContext, HttpContext httpContext,
string routeName, string? routeName,
object values, object? values,
PathString? pathBase = default, PathString? pathBase = default,
FragmentString fragment = default, FragmentString fragment = default,
LinkOptions options = default) LinkOptions? options = default)
{ {
if (generator == null) if (generator == null)
{ {
@ -70,13 +70,13 @@ 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 static string GetPathByRouteValues( public static string? GetPathByRouteValues(
this LinkGenerator generator, this LinkGenerator generator,
string routeName, string? routeName,
object values, object? values,
PathString pathBase = default, PathString pathBase = default,
FragmentString fragment = default, FragmentString fragment = default,
LinkOptions options = default) LinkOptions? options = default)
{ {
if (generator == null) if (generator == null)
{ {
@ -118,16 +118,16 @@ namespace Microsoft.AspNetCore.Routing
/// your deployment environment. /// your deployment environment.
/// </para> /// </para>
/// </remarks> /// </remarks>
public static string GetUriByRouteValues( public static string? GetUriByRouteValues(
this LinkGenerator generator, this LinkGenerator generator,
HttpContext httpContext, HttpContext httpContext,
string routeName, string? routeName,
object values, object? values,
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 = default) LinkOptions? options = default)
{ {
if (generator == null) if (generator == null)
{ {
@ -178,15 +178,15 @@ namespace Microsoft.AspNetCore.Routing
/// your deployment environment. /// your deployment environment.
/// </para> /// </para>
/// </remarks> /// </remarks>
public static string GetUriByRouteValues( public static string? GetUriByRouteValues(
this LinkGenerator generator, this LinkGenerator generator,
string routeName, string? routeName,
object values, object? values,
string scheme, string scheme,
HostString host, HostString host,
PathString pathBase = default, PathString pathBase = default,
FragmentString fragment = default, FragmentString fragment = default,
LinkOptions options = default) LinkOptions? options = default)
{ {
if (generator == null) if (generator == null)
{ {
@ -197,7 +197,7 @@ namespace Microsoft.AspNetCore.Routing
return generator.GetUriByAddress<RouteValuesAddress>(address, address.ExplicitValues, scheme, host, pathBase, fragment, options); return generator.GetUriByAddress<RouteValuesAddress>(address, address.ExplicitValues, scheme, host, pathBase, fragment, options);
} }
private static RouteValuesAddress CreateAddress(HttpContext httpContext, string routeName, object values) private static RouteValuesAddress CreateAddress(HttpContext? httpContext, string? routeName, object? values)
{ {
return new RouteValuesAddress() return new RouteValuesAddress()
{ {

View File

@ -32,6 +32,6 @@ namespace Microsoft.AspNetCore.Routing
/// of the route patterns match the provided URI path. /// of the route patterns match the provided URI path.
/// </para> /// </para>
/// </remarks> /// </remarks>
public abstract RouteValueDictionary ParsePathByAddress<TAddress>(TAddress address, PathString path); public abstract RouteValueDictionary? ParsePathByAddress<TAddress>(TAddress address, PathString path);
} }
} }

View File

@ -33,7 +33,7 @@ namespace Microsoft.AspNetCore.Routing
/// of the route patterns match the provided URI path. /// of the route patterns match the provided URI path.
/// </para> /// </para>
/// </remarks> /// </remarks>
public static RouteValueDictionary ParsePathByEndpointName( public static RouteValueDictionary? ParsePathByEndpointName(
this LinkParser parser, this LinkParser parser,
string endpointName, string endpointName,
PathString path) PathString path)

View File

@ -8,7 +8,7 @@ namespace Microsoft.AspNetCore.Routing.Logging
{ {
internal static class RouteConstraintMatcherExtensions internal static class RouteConstraintMatcherExtensions
{ {
private static readonly Action<ILogger, object, string, IRouteConstraint, Exception> _constraintNotMatched; private static readonly Action<ILogger, object, string, IRouteConstraint, Exception?> _constraintNotMatched;
static RouteConstraintMatcherExtensions() static RouteConstraintMatcherExtensions()
{ {

View File

@ -8,7 +8,7 @@ namespace Microsoft.AspNetCore.Routing.Logging
{ {
internal static class RouterMiddlewareLoggerExtensions internal static class RouterMiddlewareLoggerExtensions
{ {
private static readonly Action<ILogger, Exception> _requestNotMatched; private static readonly Action<ILogger, Exception?> _requestNotMatched;
static RouterMiddlewareLoggerExtensions() static RouterMiddlewareLoggerExtensions()
{ {

View File

@ -8,7 +8,7 @@ namespace Microsoft.AspNetCore.Routing.Logging
{ {
internal static class TreeRouterLoggerExtensions internal static class TreeRouterLoggerExtensions
{ {
private static readonly Action<ILogger, string, string, Exception> _requestMatchedRoute; private static readonly Action<ILogger, string, string, Exception?> _requestMatchedRoute;
static TreeRouterLoggerExtensions() static TreeRouterLoggerExtensions()
{ {

View File

@ -154,7 +154,7 @@ namespace Microsoft.AspNetCore.Builder
return routeConstraint; return routeConstraint;
} }
var parameterPolicy = _parameterPolicyFactory.Create(null, inlineConstraint); var parameterPolicy = _parameterPolicyFactory.Create(null!, inlineConstraint);
if (parameterPolicy != null) if (parameterPolicy != null)
{ {
// Logic inside Route will skip adding NullRouteConstraint // Logic inside Route will skip adding NullRouteConstraint

View File

@ -7,6 +7,7 @@ using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
@ -176,7 +177,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
/// The <see cref="RouteValueDictionary"/> to replace the original <see cref="RouteValueDictionary"/> at /// The <see cref="RouteValueDictionary"/> to replace the original <see cref="RouteValueDictionary"/> at
/// the <paramref name="index"/>. /// the <paramref name="index"/>.
/// </param> /// </param>
public void ReplaceEndpoint(int index, Endpoint endpoint, RouteValueDictionary values) public void ReplaceEndpoint(int index, Endpoint? endpoint, RouteValueDictionary? values)
{ {
// Friendliness for inlining // Friendliness for inlining
if ((uint)index >= Count) if ((uint)index >= Count)
@ -184,7 +185,9 @@ namespace Microsoft.AspNetCore.Routing.Matching
ThrowIndexArgumentOutOfRangeException(); ThrowIndexArgumentOutOfRangeException();
} }
Candidates[index] = new CandidateState(endpoint, values, Candidates[index].Score); // CandidateState allows a null-valued endpoint. However a validate candidate should never have a null endpoint
// We'll make lives easier for matcher policies by declaring it as non-null.
Candidates[index] = new CandidateState(endpoint!, values, Candidates[index].Score);
if (endpoint == null) if (endpoint == null)
{ {
@ -354,7 +357,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
{ {
if (GetOriginalScore(i) == score) if (GetOriginalScore(i) == score)
{ {
duplicates.Add(candidates[i].Endpoint); duplicates.Add(candidates[i].Endpoint!);
} }
} }
@ -366,11 +369,13 @@ namespace Microsoft.AspNetCore.Routing.Matching
} }
} }
[DoesNotReturn]
private static void ThrowIndexArgumentOutOfRangeException() private static void ThrowIndexArgumentOutOfRangeException()
{ {
throw new ArgumentOutOfRangeException("index"); throw new ArgumentOutOfRangeException("index");
} }
[DoesNotReturn]
private static void ThrowArgumentNullException(string parameter) private static void ThrowArgumentNullException(string parameter)
{ {
throw new ArgumentNullException(parameter); throw new ArgumentNullException(parameter);

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 Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
Values = null; Values = null;
} }
internal CandidateState(Endpoint endpoint, RouteValueDictionary values, int score) internal CandidateState(Endpoint endpoint, RouteValueDictionary? values, int score)
{ {
Endpoint = endpoint; Endpoint = endpoint;
Values = values; Values = values;
@ -50,6 +50,6 @@ namespace Microsoft.AspNetCore.Routing.Matching
/// Gets <see cref="RouteValueDictionary"/> associated with the /// Gets <see cref="RouteValueDictionary"/> associated with the
/// <see cref="Http.Endpoint"/> and the current request. /// <see cref="Http.Endpoint"/> and the current request.
/// </summary> /// </summary>
public RouteValueDictionary Values { get; internal set; } public RouteValueDictionary? Values { get; internal set; }
} }
} }

View File

@ -57,10 +57,10 @@ namespace Microsoft.AspNetCore.Routing.Matching
public sealed class Lifetime : IDisposable public sealed class Lifetime : IDisposable
{ {
private readonly object _lock = new object(); private readonly object _lock = new object();
private DataSourceDependentCache<Matcher> _cache; private DataSourceDependentCache<Matcher>? _cache;
private bool _disposed; private bool _disposed;
public DataSourceDependentCache<Matcher> Cache public DataSourceDependentCache<Matcher>? Cache
{ {
get => _cache; get => _cache;
set set

View File

@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
if (CandidateSet.IsValidCandidate(ref state)) if (CandidateSet.IsValidCandidate(ref state))
{ {
httpContext.SetEndpoint(state.Endpoint); httpContext.SetEndpoint(state.Endpoint);
httpContext.Request.RouteValues = state.Values; httpContext.Request.RouteValues = state.Values!;
} }
break; break;
@ -67,8 +67,8 @@ namespace Microsoft.AspNetCore.Routing.Matching
HttpContext httpContext, HttpContext httpContext,
CandidateState[] candidateState) CandidateState[] candidateState)
{ {
Endpoint endpoint = null; Endpoint? endpoint = null;
RouteValueDictionary values = null; RouteValueDictionary? values = null;
int? foundScore = null; int? foundScore = null;
for (var i = 0; i < candidateState.Length; i++) for (var i = 0; i < candidateState.Length; i++)
{ {
@ -110,7 +110,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
if (endpoint != null) if (endpoint != null)
{ {
httpContext.SetEndpoint(endpoint); httpContext.SetEndpoint(endpoint);
httpContext.Request.RouteValues = values; httpContext.Request.RouteValues = values!;
} }
} }

View File

@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
// The sequence of actions we take is optimized to avoid doing expensive work // The sequence of actions we take is optimized to avoid doing expensive work
// like creating substrings, creating route value dictionaries, and calling // like creating substrings, creating route value dictionaries, and calling
// into policies like versioning. // into policies like versioning.
var path = httpContext.Request.Path.Value; var path = httpContext.Request.Path.Value!;
// First tokenize the path into series of segments. // First tokenize the path into series of segments.
Span<PathSegment> buffer = stackalloc PathSegment[_maxSegmentCount]; Span<PathSegment> buffer = stackalloc PathSegment[_maxSegmentCount];
@ -119,7 +119,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
// We want to create a new array for the route values based on Slots // We want to create a new array for the route values based on Slots
// as a prototype. // as a prototype.
var prototype = candidate.Slots; var prototype = candidate.Slots;
var slots = new KeyValuePair<string, object>[prototype.Length]; var slots = new KeyValuePair<string, object?>[prototype.Length];
if ((flags & Candidate.CandidateFlags.HasDefaults) != 0) if ((flags & Candidate.CandidateFlags.HasDefaults) != 0)
{ {
@ -221,7 +221,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
} }
private void ProcessCaptures( private void ProcessCaptures(
KeyValuePair<string, object>[] slots, KeyValuePair<string, object?>[] slots,
(string parameterName, int segmentIndex, int slotIndex)[] captures, (string parameterName, int segmentIndex, int slotIndex)[] captures,
string path, string path,
ReadOnlySpan<PathSegment> segments) ReadOnlySpan<PathSegment> segments)
@ -235,7 +235,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
var segment = segments[segmentIndex]; var segment = segments[segmentIndex];
if (parameterName != null && segment.Length > 0) if (parameterName != null && segment.Length > 0)
{ {
slots[slotIndex] = new KeyValuePair<string, object>( slots[slotIndex] = new KeyValuePair<string, object?>(
parameterName, parameterName,
path.Substring(segment.Start, segment.Length)); path.Substring(segment.Start, segment.Length));
} }
@ -244,7 +244,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
} }
private void ProcessCatchAll( private void ProcessCatchAll(
KeyValuePair<string, object>[] slots, KeyValuePair<string, object?>[] slots,
in (string parameterName, int segmentIndex, int slotIndex) catchAll, in (string parameterName, int segmentIndex, int slotIndex) catchAll,
string path, string path,
ReadOnlySpan<PathSegment> segments) ReadOnlySpan<PathSegment> segments)
@ -255,7 +255,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
if ((uint)segmentIndex < (uint)segments.Length) if ((uint)segmentIndex < (uint)segments.Length)
{ {
var segment = segments[segmentIndex]; var segment = segments[segmentIndex];
slots[catchAll.slotIndex] = new KeyValuePair<string, object>( slots[catchAll.slotIndex] = new KeyValuePair<string, object?>(
catchAll.parameterName, catchAll.parameterName,
path.Substring(segment.Start)); path.Substring(segment.Start));
} }
@ -333,6 +333,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
public static readonly EventId CandidateValid = new EventId(1005, "CandiateValid"); public static readonly EventId CandidateValid = new EventId(1005, "CandiateValid");
} }
#nullable disable
private static class Logger private static class Logger
{ {
private static readonly Action<ILogger, string, Exception> _candidatesNotFound = LoggerMessage.Define<string>( private static readonly Action<ILogger, string, Exception> _candidatesNotFound = LoggerMessage.Define<string>(

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 disable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
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 disable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;

View File

@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
} }
} }
public int Compare(Endpoint x, Endpoint y) public int Compare(Endpoint? x, Endpoint? y)
{ {
// We don't expose this publicly, and we should never call it on // We don't expose this publicly, and we should never call it on
// a null endpoint. // a null endpoint.
@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
return 0; return 0;
} }
public bool Equals(Endpoint x, Endpoint y) public bool Equals(Endpoint? x, Endpoint? y)
{ {
// We don't expose this publicly, and we should never call it on // We don't expose this publicly, and we should never call it on
// a null endpoint. // a null endpoint.
@ -109,7 +109,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
{ {
public static readonly IComparer<Endpoint> Instance = new OrderComparer(); public static readonly IComparer<Endpoint> Instance = new OrderComparer();
public int Compare(Endpoint x, Endpoint y) public int Compare(Endpoint? x, Endpoint? y)
{ {
var routeEndpointX = x as RouteEndpoint; var routeEndpointX = x as RouteEndpoint;
var routeEndpointY = y as RouteEndpoint; var routeEndpointY = y as RouteEndpoint;
@ -136,7 +136,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
{ {
public static readonly IComparer<Endpoint> Instance = new PrecedenceComparer(); public static readonly IComparer<Endpoint> Instance = new PrecedenceComparer();
public int Compare(Endpoint x, Endpoint y) public int Compare(Endpoint? x, Endpoint? y)
{ {
var routeEndpointX = x as RouteEndpoint; var routeEndpointX = x as RouteEndpoint;
var routeEndpointY = y as RouteEndpoint; var routeEndpointY = y as RouteEndpoint;

View File

@ -342,7 +342,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
private class HostMetadataEndpointComparer : EndpointMetadataComparer<IHostMetadata> private class HostMetadataEndpointComparer : EndpointMetadataComparer<IHostMetadata>
{ {
protected override int CompareMetadata(IHostMetadata x, IHostMetadata y) protected override int CompareMetadata(IHostMetadata? x, IHostMetadata? y)
{ {
// Ignore the metadata if it has an empty list of hosts. // Ignore the metadata if it has an empty list of hosts.
return base.CompareMetadata( return base.CompareMetadata(
@ -391,9 +391,9 @@ namespace Microsoft.AspNetCore.Routing.Matching
public readonly int? Port; public readonly int? Port;
public readonly string Host; public readonly string Host;
private readonly string _wildcardEndsWith; private readonly string? _wildcardEndsWith;
public EdgeKey(string host, int? port) public EdgeKey(string? host, int? port)
{ {
Host = host ?? WildcardHost; Host = host ?? WildcardHost;
Port = port; Port = port;
@ -421,9 +421,9 @@ namespace Microsoft.AspNetCore.Routing.Matching
return Comparer<int?>.Default.Compare(Port, other.Port); return Comparer<int?>.Default.Compare(Port, other.Port);
} }
public int CompareTo(object obj) public int CompareTo(object? obj)
{ {
return CompareTo((EdgeKey)obj); return CompareTo((EdgeKey)obj!);
} }
public bool Equals(EdgeKey other) public bool Equals(EdgeKey other)
@ -437,7 +437,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
{ {
if (HasHostWildcard) if (HasHostWildcard)
{ {
return host.EndsWith(_wildcardEndsWith, StringComparison.OrdinalIgnoreCase); return host.EndsWith(_wildcardEndsWith!, StringComparison.OrdinalIgnoreCase);
} }
else else
{ {
@ -454,7 +454,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
return (Host?.GetHashCode() ?? 0) ^ (Port?.GetHashCode() ?? 0); return (Host?.GetHashCode() ?? 0) ^ (Port?.GetHashCode() ?? 0);
} }
public override bool Equals(object obj) public override bool Equals(object? obj)
{ {
if (obj is EdgeKey key) if (obj is EdgeKey key)
{ {

View File

@ -108,7 +108,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
// We want to return a 405 iff we eliminated ALL of the currently valid endpoints due to HTTP method // We want to return a 405 iff we eliminated ALL of the currently valid endpoints due to HTTP method
// mismatch. // mismatch.
bool? needs405Endpoint = null; bool? needs405Endpoint = null;
HashSet<string> methods = null; HashSet<string>? methods = null;
for (var i = 0; i < candidates.Count; i++) for (var i = 0; i < candidates.Count; i++)
{ {
@ -168,8 +168,8 @@ namespace Microsoft.AspNetCore.Routing.Matching
if (needs405Endpoint == true) if (needs405Endpoint == true)
{ {
// We saw some endpoints coming in, and we eliminated them all. // We saw some endpoints coming in, and we eliminated them all.
httpContext.SetEndpoint(CreateRejectionEndpoint(methods.OrderBy(m => m, StringComparer.OrdinalIgnoreCase))); httpContext.SetEndpoint(CreateRejectionEndpoint(methods!.OrderBy(m => m, StringComparer.OrdinalIgnoreCase)));
httpContext.Request.RouteValues = null; httpContext.Request.RouteValues = null!;
} }
return Task.CompletedTask; return Task.CompletedTask;
@ -329,8 +329,8 @@ namespace Microsoft.AspNetCore.Routing.Matching
/// <returns></returns> /// <returns></returns>
public PolicyJumpTable BuildJumpTable(int exitDestination, IReadOnlyList<PolicyJumpTableEdge> edges) public PolicyJumpTable BuildJumpTable(int exitDestination, IReadOnlyList<PolicyJumpTableEdge> edges)
{ {
Dictionary<string, int> destinations = null; Dictionary<string, int>? destinations = null;
Dictionary<string, int> corsPreflightDestinations = null; Dictionary<string, int>? corsPreflightDestinations = null;
for (var i = 0; i < edges.Count; i++) for (var i = 0; i < edges.Count; i++)
{ {
// We create this data, so it's safe to cast it. // We create this data, so it's safe to cast it.
@ -421,17 +421,17 @@ namespace Microsoft.AspNetCore.Routing.Matching
private class HttpMethodPolicyJumpTable : PolicyJumpTable private class HttpMethodPolicyJumpTable : PolicyJumpTable
{ {
private readonly int _exitDestination; private readonly int _exitDestination;
private readonly Dictionary<string, int> _destinations; private readonly Dictionary<string, int>? _destinations;
private readonly int _corsPreflightExitDestination; private readonly int _corsPreflightExitDestination;
private readonly Dictionary<string, int> _corsPreflightDestinations; private readonly Dictionary<string, int>? _corsPreflightDestinations;
private readonly bool _supportsCorsPreflight; private readonly bool _supportsCorsPreflight;
public HttpMethodPolicyJumpTable( public HttpMethodPolicyJumpTable(
int exitDestination, int exitDestination,
Dictionary<string, int> destinations, Dictionary<string, int>? destinations,
int corsPreflightExitDestination, int corsPreflightExitDestination,
Dictionary<string, int> corsPreflightDestinations) Dictionary<string, int>? corsPreflightDestinations)
{ {
_exitDestination = exitDestination; _exitDestination = exitDestination;
_destinations = destinations; _destinations = destinations;
@ -466,7 +466,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
private class HttpMethodMetadataEndpointComparer : EndpointMetadataComparer<IHttpMethodMetadata> private class HttpMethodMetadataEndpointComparer : EndpointMetadataComparer<IHttpMethodMetadata>
{ {
protected override int CompareMetadata(IHttpMethodMetadata x, IHttpMethodMetadata y) protected override int CompareMetadata(IHttpMethodMetadata? x, IHttpMethodMetadata? y)
{ {
// Ignore the metadata if it has an empty list of HTTP methods. // Ignore the metadata if it has an empty list of HTTP methods.
return base.CompareMetadata( return base.CompareMetadata(
@ -501,9 +501,9 @@ namespace Microsoft.AspNetCore.Routing.Matching
return IsCorsPreflightRequest.CompareTo(other.IsCorsPreflightRequest); return IsCorsPreflightRequest.CompareTo(other.IsCorsPreflightRequest);
} }
public int CompareTo(object obj) public int CompareTo(object? obj)
{ {
return CompareTo((EdgeKey)obj); return CompareTo((EdgeKey)obj!);
} }
public bool Equals(EdgeKey other) public bool Equals(EdgeKey other)
@ -513,7 +513,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
HttpMethods.Equals(HttpMethod, other.HttpMethod); HttpMethods.Equals(HttpMethod, other.HttpMethod);
} }
public override bool Equals(object obj) public override bool Equals(object? obj)
{ {
var other = obj as EdgeKey?; var other = obj as EdgeKey?;
return other == null ? false : Equals(other.Value); return other == null ? false : Equals(other.Value);

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 disable
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 disable
using System; using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;

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;
@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Routing.Matching
Length = length; Length = length;
} }
public override bool Equals(object obj) public override bool Equals(object? obj)
{ {
return obj is PathSegment segment ? Equals(segment) : false; return obj is PathSegment segment ? Equals(segment) : false;
} }

View File

@ -12,7 +12,7 @@ Microsoft.AspNetCore.Routing.RouteCollection</Description>
<PackageTags>aspnetcore;routing</PackageTags> <PackageTags>aspnetcore;routing</PackageTags>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<Nullable>annotations</Nullable> <Nullable>enable</Nullable>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>

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.Threading.Tasks; using System.Threading.Tasks;
@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Routing
{ {
} }
public VirtualPathData GetVirtualPath(VirtualPathContext context) public VirtualPathData? GetVirtualPath(VirtualPathContext context)
{ {
return null; return null;
} }

View File

@ -1,12 +1,13 @@
// 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 disable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Routing namespace Microsoft.AspNetCore.Routing

View File

@ -26,7 +26,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="parameterPolicy">An existing parameter policy.</param> /// <param name="parameterPolicy">An existing parameter policy.</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, IParameterPolicy parameterPolicy); public abstract IParameterPolicy Create(RoutePatternParameterPart? parameter, IParameterPolicy parameterPolicy);
/// <summary> /// <summary>
/// Creates a parameter policy. /// Creates a parameter policy.
@ -34,7 +34,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="reference">The reference to resolve.</param> /// <param name="reference">The reference to resolve.</param>
/// <returns>The <see cref="IParameterPolicy"/> for the parameter.</returns> /// <returns>The <see cref="IParameterPolicy"/> for the parameter.</returns>
public IParameterPolicy Create(RoutePatternParameterPart parameter, RoutePatternParameterPolicyReference reference) public IParameterPolicy Create(RoutePatternParameterPart? parameter, RoutePatternParameterPolicyReference reference)
{ {
if (reference == null) if (reference == 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 disable
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;

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 disable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;

View File

@ -78,7 +78,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
var parseResults = ParseConstraints(parameter, currentIndex, endIndex); var parseResults = ParseConstraints(parameter, currentIndex, endIndex);
currentIndex = parseResults.CurrentIndex; currentIndex = parseResults.CurrentIndex;
string defaultValue = null; string? defaultValue = null;
if (currentIndex <= endIndex && if (currentIndex <= endIndex &&
parameter[currentIndex] == '=') parameter[currentIndex] == '=')
{ {

View File

@ -27,7 +27,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// </remarks> /// </remarks>
public static readonly object RequiredValueAny = new RequiredValueAnySentinal(); public static readonly object RequiredValueAny = new RequiredValueAnySentinal();
internal static bool IsRequiredValueAny(object value) internal static bool IsRequiredValueAny(object? value)
{ {
return object.ReferenceEquals(RequiredValueAny, value); return object.ReferenceEquals(RequiredValueAny, value);
} }
@ -35,10 +35,10 @@ namespace Microsoft.AspNetCore.Routing.Patterns
private const string SeparatorString = "/"; private const string SeparatorString = "/";
internal RoutePattern( internal RoutePattern(
string rawText, string? rawText,
IReadOnlyDictionary<string, object> defaults, IReadOnlyDictionary<string, object?> defaults,
IReadOnlyDictionary<string, IReadOnlyList<RoutePatternParameterPolicyReference>> parameterPolicies, IReadOnlyDictionary<string, IReadOnlyList<RoutePatternParameterPolicyReference>> parameterPolicies,
IReadOnlyDictionary<string, object> requiredValues, IReadOnlyDictionary<string, object?> requiredValues,
IReadOnlyList<RoutePatternParameterPart> parameters, IReadOnlyList<RoutePatternParameterPart> parameters,
IReadOnlyList<RoutePatternPathSegment> pathSegments) IReadOnlyList<RoutePatternPathSegment> pathSegments)
{ {
@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// Gets the set of default values for the route pattern. /// Gets the set of default values for the route pattern.
/// The keys of <see cref="Defaults"/> are the route parameter names. /// The keys of <see cref="Defaults"/> are the route parameter names.
/// </summary> /// </summary>
public IReadOnlyDictionary<string, object> Defaults { get; } public IReadOnlyDictionary<string, object?> Defaults { get; }
/// <summary> /// <summary>
/// Gets the set of parameter policy references for the route pattern. /// Gets the set of parameter policy references for the route pattern.
@ -92,7 +92,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// </example> /// </example>
/// </para> /// </para>
/// </remarks> /// </remarks>
public IReadOnlyDictionary<string, object> RequiredValues { get; } public IReadOnlyDictionary<string, object?> RequiredValues { get; }
/// <summary> /// <summary>
/// Gets the precedence value of the route pattern for URL matching. /// Gets the precedence value of the route pattern for URL matching.
@ -115,7 +115,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// <summary> /// <summary>
/// Gets the raw text supplied when parsing the route pattern. May be null. /// Gets the raw text supplied when parsing the route pattern. May be null.
/// </summary> /// </summary>
public string RawText { get; } public string? RawText { get; }
/// <summary> /// <summary>
/// Gets the list of route parameters. /// Gets the list of route parameters.
@ -132,7 +132,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// </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 RoutePatternParameterPart GetParameter(string name) public RoutePatternParameterPart? GetParameter(string name)
{ {
if (name == null) if (name == null)
{ {

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;
@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
private RoutePatternException(SerializationInfo info, StreamingContext context) private RoutePatternException(SerializationInfo info, StreamingContext context)
: base(info, context) : base(info, context)
{ {
Pattern = (string)info.GetValue(nameof(Pattern), typeof(string)); Pattern = (string)info.GetValue(nameof(Pattern), typeof(string))!;
} }
/// <summary> /// <summary>

View File

@ -17,8 +17,8 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// </summary> /// </summary>
public static class RoutePatternFactory public static class RoutePatternFactory
{ {
private static readonly IReadOnlyDictionary<string, object> EmptyDictionary = private static readonly IReadOnlyDictionary<string, object?> EmptyDictionary =
new ReadOnlyDictionary<string, object>(new Dictionary<string, object>()); new ReadOnlyDictionary<string, object?>(new Dictionary<string, object?>());
private static readonly IReadOnlyDictionary<string, IReadOnlyList<RoutePatternParameterPolicyReference>> EmptyPoliciesDictionary = private static readonly IReadOnlyDictionary<string, IReadOnlyList<RoutePatternParameterPolicyReference>> EmptyPoliciesDictionary =
new ReadOnlyDictionary<string, IReadOnlyList<RoutePatternParameterPolicyReference>>(new Dictionary<string, IReadOnlyList<RoutePatternParameterPolicyReference>>()); new ReadOnlyDictionary<string, IReadOnlyList<RoutePatternParameterPolicyReference>>(new Dictionary<string, IReadOnlyList<RoutePatternParameterPolicyReference>>());
@ -55,7 +55,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// Multiple policies can be specified for a key by providing a collection as the value. /// Multiple policies can be specified for a key by providing a collection as the value.
/// </param> /// </param>
/// <returns>The <see cref="RoutePattern"/>.</returns> /// <returns>The <see cref="RoutePattern"/>.</returns>
public static RoutePattern Parse(string pattern, object defaults, object parameterPolicies) public static RoutePattern Parse(string pattern, object? defaults, object? parameterPolicies)
{ {
if (pattern == null) if (pattern == null)
{ {
@ -86,7 +86,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// Route values that can be substituted for parameters in the route pattern. See remarks on <see cref="RoutePattern.RequiredValues"/>. /// Route values that can be substituted for parameters in the route pattern. See remarks on <see cref="RoutePattern.RequiredValues"/>.
/// </param> /// </param>
/// <returns>The <see cref="RoutePattern"/>.</returns> /// <returns>The <see cref="RoutePattern"/>.</returns>
public static RoutePattern Parse(string pattern, object defaults, object parameterPolicies, object requiredValues) public static RoutePattern Parse(string pattern, object? defaults, object? parameterPolicies, object? requiredValues)
{ {
if (pattern == null) if (pattern == null)
{ {
@ -118,7 +118,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// <param name="rawText">The raw text to associate with the route pattern. May be null.</param> /// <param name="rawText">The raw text to associate with the route pattern. May be null.</param>
/// <param name="segments">The collection of segments.</param> /// <param name="segments">The collection of segments.</param>
/// <returns>The <see cref="RoutePattern"/>.</returns> /// <returns>The <see cref="RoutePattern"/>.</returns>
public static RoutePattern Pattern(string rawText, IEnumerable<RoutePatternPathSegment> segments) public static RoutePattern Pattern(string? rawText, IEnumerable<RoutePatternPathSegment> segments)
{ {
if (segments == null) if (segments == null)
{ {
@ -146,8 +146,8 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// <param name="segments">The collection of segments.</param> /// <param name="segments">The collection of segments.</param>
/// <returns>The <see cref="RoutePattern"/>.</returns> /// <returns>The <see cref="RoutePattern"/>.</returns>
public static RoutePattern Pattern( public static RoutePattern Pattern(
object defaults, object? defaults,
object parameterPolicies, object? parameterPolicies,
IEnumerable<RoutePatternPathSegment> segments) IEnumerable<RoutePatternPathSegment> segments)
{ {
if (segments == null) if (segments == null)
@ -177,9 +177,9 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// <param name="segments">The collection of segments.</param> /// <param name="segments">The collection of segments.</param>
/// <returns>The <see cref="RoutePattern"/>.</returns> /// <returns>The <see cref="RoutePattern"/>.</returns>
public static RoutePattern Pattern( public static RoutePattern Pattern(
string rawText, string? rawText,
object defaults, object? defaults,
object parameterPolicies, object? parameterPolicies,
IEnumerable<RoutePatternPathSegment> segments) IEnumerable<RoutePatternPathSegment> segments)
{ {
if (segments == null) if (segments == null)
@ -239,8 +239,8 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// <param name="segments">The collection of segments.</param> /// <param name="segments">The collection of segments.</param>
/// <returns>The <see cref="RoutePattern"/>.</returns> /// <returns>The <see cref="RoutePattern"/>.</returns>
public static RoutePattern Pattern( public static RoutePattern Pattern(
object defaults, object? defaults,
object parameterPolicies, object? parameterPolicies,
params RoutePatternPathSegment[] segments) params RoutePatternPathSegment[] segments)
{ {
if (segments == null) if (segments == null)
@ -270,9 +270,9 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// <param name="segments">The collection of segments.</param> /// <param name="segments">The collection of segments.</param>
/// <returns>The <see cref="RoutePattern"/>.</returns> /// <returns>The <see cref="RoutePattern"/>.</returns>
public static RoutePattern Pattern( public static RoutePattern Pattern(
string rawText, string? rawText,
object defaults, object? defaults,
object parameterPolicies, object? parameterPolicies,
params RoutePatternPathSegment[] segments) params RoutePatternPathSegment[] segments)
{ {
if (segments == null) if (segments == null)
@ -284,10 +284,10 @@ namespace Microsoft.AspNetCore.Routing.Patterns
} }
private static RoutePattern PatternCore( private static RoutePattern PatternCore(
string rawText, string? rawText,
RouteValueDictionary defaults, RouteValueDictionary? defaults,
RouteValueDictionary parameterPolicies, RouteValueDictionary? parameterPolicies,
RouteValueDictionary requiredValues, RouteValueDictionary? requiredValues,
IEnumerable<RoutePatternPathSegment> segments) IEnumerable<RoutePatternPathSegment> segments)
{ {
// We want to merge the segment data with the 'out of line' defaults and parameter policies. // We want to merge the segment data with the 'out of line' defaults and parameter policies.
@ -301,10 +301,10 @@ namespace Microsoft.AspNetCore.Routing.Patterns
// It's important that these two views of the data are consistent. We don't want // It's important that these two views of the data are consistent. We don't want
// values specified out of line to have a different behavior. // values specified out of line to have a different behavior.
Dictionary<string, object> updatedDefaults = null; Dictionary<string, object?>? updatedDefaults = null;
if (defaults != null && defaults.Count > 0) if (defaults != null && defaults.Count > 0)
{ {
updatedDefaults = new Dictionary<string, object>(defaults.Count, StringComparer.OrdinalIgnoreCase); updatedDefaults = new Dictionary<string, object?>(defaults.Count, StringComparer.OrdinalIgnoreCase);
foreach (var kvp in defaults) foreach (var kvp in defaults)
{ {
@ -312,7 +312,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
} }
} }
Dictionary<string, List<RoutePatternParameterPolicyReference>> updatedParameterPolicies = null; Dictionary<string, List<RoutePatternParameterPolicyReference>>? updatedParameterPolicies = null;
if (parameterPolicies != null && parameterPolicies.Count > 0) if (parameterPolicies != null && parameterPolicies.Count > 0)
{ {
updatedParameterPolicies = new Dictionary<string, List<RoutePatternParameterPolicyReference>>(parameterPolicies.Count, StringComparer.OrdinalIgnoreCase); updatedParameterPolicies = new Dictionary<string, List<RoutePatternParameterPolicyReference>>(parameterPolicies.Count, StringComparer.OrdinalIgnoreCase);
@ -349,7 +349,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
} }
} }
List<RoutePatternParameterPart> parameters = null; List<RoutePatternParameterPart>? parameters = null;
var updatedSegments = segments.ToArray(); var updatedSegments = segments.ToArray();
for (var i = 0; i < updatedSegments.Length; i++) for (var i = 0; i < updatedSegments.Length; i++)
{ {
@ -420,12 +420,12 @@ namespace Microsoft.AspNetCore.Routing.Patterns
? updatedParameterPolicies.ToDictionary(kvp => kvp.Key, kvp => (IReadOnlyList<RoutePatternParameterPolicyReference>)kvp.Value.ToArray()) ? updatedParameterPolicies.ToDictionary(kvp => kvp.Key, kvp => (IReadOnlyList<RoutePatternParameterPolicyReference>)kvp.Value.ToArray())
: EmptyPoliciesDictionary, : EmptyPoliciesDictionary,
requiredValues ?? EmptyDictionary, requiredValues ?? EmptyDictionary,
(IReadOnlyList<RoutePatternParameterPart>)parameters ?? Array.Empty<RoutePatternParameterPart>(), (IReadOnlyList<RoutePatternParameterPart>?)parameters ?? Array.Empty<RoutePatternParameterPart>(),
updatedSegments); updatedSegments);
RoutePatternPathSegment VisitSegment(RoutePatternPathSegment segment) RoutePatternPathSegment VisitSegment(RoutePatternPathSegment segment)
{ {
RoutePatternPart[] updatedParts = null; RoutePatternPart[]? updatedParts = null;
for (var i = 0; i < segment.Parts.Count; i++) for (var i = 0; i < segment.Parts.Count; i++)
{ {
var part = segment.Parts[i]; var part = segment.Parts[i];
@ -482,13 +482,13 @@ namespace Microsoft.AspNetCore.Routing.Patterns
{ {
if (updatedDefaults == null) if (updatedDefaults == null)
{ {
updatedDefaults = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase); updatedDefaults = new Dictionary<string, object?>(StringComparer.OrdinalIgnoreCase);
} }
updatedDefaults[parameter.Name] = parameter.Default; updatedDefaults[parameter.Name] = parameter.Default;
} }
List<RoutePatternParameterPolicyReference> parameterConstraints = null; List<RoutePatternParameterPolicyReference>? parameterConstraints = null;
if ((updatedParameterPolicies == null || !updatedParameterPolicies.TryGetValue(parameter.Name, out parameterConstraints)) && if ((updatedParameterPolicies == null || !updatedParameterPolicies.TryGetValue(parameter.Name, out parameterConstraints)) &&
parameter.ParameterPolicies.Count > 0) parameter.ParameterPolicies.Count > 0)
{ {
@ -503,7 +503,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
if (parameter.ParameterPolicies.Count > 0) if (parameter.ParameterPolicies.Count > 0)
{ {
parameterConstraints.AddRange(parameter.ParameterPolicies); parameterConstraints!.AddRange(parameter.ParameterPolicies);
} }
if (Equals(parameter.Default, @default) if (Equals(parameter.Default, @default)
@ -667,7 +667,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// <returns>The <see cref="RoutePatternParameterPart"/>.</returns> /// <returns>The <see cref="RoutePatternParameterPart"/>.</returns>
public static RoutePatternParameterPart ParameterPart( public static RoutePatternParameterPart ParameterPart(
string parameterName, string parameterName,
object @default, object? @default,
RoutePatternParameterKind parameterKind) RoutePatternParameterKind parameterKind)
{ {
if (string.IsNullOrEmpty(parameterName)) if (string.IsNullOrEmpty(parameterName))
@ -703,7 +703,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// <returns>The <see cref="RoutePatternParameterPart"/>.</returns> /// <returns>The <see cref="RoutePatternParameterPart"/>.</returns>
public static RoutePatternParameterPart ParameterPart( public static RoutePatternParameterPart ParameterPart(
string parameterName, string parameterName,
object @default, object? @default,
RoutePatternParameterKind parameterKind, RoutePatternParameterKind parameterKind,
IEnumerable<RoutePatternParameterPolicyReference> parameterPolicies) IEnumerable<RoutePatternParameterPolicyReference> parameterPolicies)
{ {
@ -745,7 +745,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// <returns>The <see cref="RoutePatternParameterPart"/>.</returns> /// <returns>The <see cref="RoutePatternParameterPart"/>.</returns>
public static RoutePatternParameterPart ParameterPart( public static RoutePatternParameterPart ParameterPart(
string parameterName, string parameterName,
object @default, object? @default,
RoutePatternParameterKind parameterKind, RoutePatternParameterKind parameterKind,
params RoutePatternParameterPolicyReference[] parameterPolicies) params RoutePatternParameterPolicyReference[] parameterPolicies)
{ {
@ -778,7 +778,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
private static RoutePatternParameterPart ParameterPartCore( private static RoutePatternParameterPart ParameterPartCore(
string parameterName, string parameterName,
object @default, object? @default,
RoutePatternParameterKind parameterKind, RoutePatternParameterKind parameterKind,
RoutePatternParameterPolicyReference[] parameterPolicies) RoutePatternParameterPolicyReference[] parameterPolicies)
{ {
@ -787,7 +787,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
private static RoutePatternParameterPart ParameterPartCore( private static RoutePatternParameterPart ParameterPartCore(
string parameterName, string parameterName,
object @default, object? @default,
RoutePatternParameterKind parameterKind, RoutePatternParameterKind parameterKind,
RoutePatternParameterPolicyReference[] parameterPolicies, RoutePatternParameterPolicyReference[] parameterPolicies,
bool encodeSlashes) bool encodeSlashes)
@ -906,7 +906,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
return new RoutePatternParameterPolicyReference(parameterPolicy); return new RoutePatternParameterPolicyReference(parameterPolicy);
} }
private static RouteValueDictionary Wrap(object values) private static RouteValueDictionary? Wrap(object? values)
{ {
return values == null ? null : new RouteValueDictionary(values); return values == null ? null : new RouteValueDictionary(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 disable
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;

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.Collections.Generic; using System.Collections.Generic;
@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
{ {
internal RoutePatternParameterPart( internal RoutePatternParameterPart(
string parameterName, string parameterName,
object @default, object? @default,
RoutePatternParameterKind parameterKind, RoutePatternParameterKind parameterKind,
RoutePatternParameterPolicyReference[] parameterPolicies) RoutePatternParameterPolicyReference[] parameterPolicies)
: this(parameterName, @default, parameterKind, parameterPolicies, encodeSlashes: true) : this(parameterName, @default, parameterKind, parameterPolicies, encodeSlashes: true)
@ -25,7 +25,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
internal RoutePatternParameterPart( internal RoutePatternParameterPart(
string parameterName, string parameterName,
object @default, object? @default,
RoutePatternParameterKind parameterKind, RoutePatternParameterKind parameterKind,
RoutePatternParameterPolicyReference[] parameterPolicies, RoutePatternParameterPolicyReference[] parameterPolicies,
bool encodeSlashes) bool encodeSlashes)
@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// <summary> /// <summary>
/// Gets the default value of this route parameter. May be null. /// Gets the default value of this route parameter. May be null.
/// </summary> /// </summary>
public object Default { get; } public object? Default { get; }
/// <summary> /// <summary>
/// Returns <c>true</c> if this part is a catch-all parameter. /// Returns <c>true</c> if this part is a catch-all parameter.

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.Diagnostics; using System.Diagnostics;
@ -26,14 +26,14 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// <summary> /// <summary>
/// Gets the constraint text. /// Gets the constraint text.
/// </summary> /// </summary>
public string Content { get; } public string? Content { get; }
/// <summary> /// <summary>
/// Gets a pre-existing <see cref="IParameterPolicy"/> that was used to construct this reference. /// Gets a pre-existing <see cref="IParameterPolicy"/> that was used to construct this reference.
/// </summary> /// </summary>
public IParameterPolicy ParameterPolicy { get; } public IParameterPolicy? ParameterPolicy { get; }
private string DebuggerToString() private string? DebuggerToString()
{ {
return Content; return Content;
} }

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 disable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;

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.Patterns namespace Microsoft.AspNetCore.Routing.Patterns
@ -30,6 +30,6 @@ namespace Microsoft.AspNetCore.Routing.Patterns
/// return <c>null</c> if any required value cannot be substituted. /// return <c>null</c> if any required value cannot be substituted.
/// </para> /// </para>
/// </remarks> /// </remarks>
public abstract RoutePattern SubstituteRequiredValues(RoutePattern original, object requiredValues); public abstract RoutePattern? SubstituteRequiredValues(RoutePattern original, object requiredValues);
} }
} }

View File

@ -259,7 +259,7 @@ namespace Microsoft.AspNetCore.Routing
new RouteHandler(handler), new RouteHandler(handler),
template, template,
defaults: null, defaults: null,
constraints: new RouteValueDictionary(new { httpMethod = new HttpMethodRouteConstraint(verb) }), constraints: new RouteValueDictionary(new { httpMethod = new HttpMethodRouteConstraint(verb) })!,
dataTokens: null, dataTokens: null,
inlineConstraintResolver: GetConstraintResolver(builder)); inlineConstraintResolver: GetConstraintResolver(builder));

View File

@ -1,8 +1,6 @@
// 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;
@ -62,7 +60,7 @@ namespace Microsoft.AspNetCore.Routing
_target = target; _target = target;
} }
public string RouteTemplate => ParsedTemplate.TemplateText; public string? RouteTemplate => ParsedTemplate.TemplateText;
protected override Task OnRouteMatched(RouteContext context) protected override Task OnRouteMatched(RouteContext context)
{ {

View File

@ -1,8 +1,6 @@
// 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;
@ -110,7 +108,7 @@ 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);
} }
@ -175,7 +173,7 @@ namespace Microsoft.AspNetCore.Routing
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!);
if (constraints != null) if (constraints != null)
{ {
@ -189,12 +187,12 @@ namespace Microsoft.AspNetCore.Routing
{ {
if (parameter.IsOptional) if (parameter.IsOptional)
{ {
constraintBuilder.SetOptional(parameter.Name); constraintBuilder.SetOptional(parameter.Name!);
} }
foreach (var inlineConstraint in parameter.InlineConstraints) foreach (var inlineConstraint in parameter.InlineConstraints)
{ {
constraintBuilder.AddResolvedConstraint(parameter.Name, inlineConstraint.Constraint); constraintBuilder.AddResolvedConstraint(parameter.Name!, inlineConstraint.Constraint);
} }
} }
@ -219,7 +217,7 @@ namespace Microsoft.AspNetCore.Routing
parameter.Name)); parameter.Name));
} }
#else #else
if (result.ContainsKey(parameter.Name)) if (result.ContainsKey(parameter.Name!))
{ {
throw new InvalidOperationException( throw new InvalidOperationException(
Resources.FormatTemplateRoute_CannotHaveDefaultValueSpecifiedInlineAndExplicitly( Resources.FormatTemplateRoute_CannotHaveDefaultValueSpecifiedInlineAndExplicitly(
@ -227,7 +225,7 @@ namespace Microsoft.AspNetCore.Routing
} }
else else
{ {
result.Add(parameter.Name, parameter.DefaultValue); result.Add(parameter.Name!, parameter.DefaultValue);
} }
#endif #endif
} }
@ -300,7 +298,7 @@ namespace Microsoft.AspNetCore.Routing
public override string ToString() public override string ToString()
{ {
return ParsedTemplate.TemplateText; return ParsedTemplate.TemplateText!;
} }
} }
} }

View File

@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.Routing
{ {
routeValues.TryGetValue(kvp.Key, out var routeValue); routeValues.TryGetValue(kvp.Key, out var routeValue);
logger.ConstraintNotMatched(routeValue, kvp.Key, kvp.Value); logger.ConstraintNotMatched(routeValue!, kvp.Key, kvp.Value);
} }
return false; return false;

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;
@ -28,8 +28,8 @@ namespace Microsoft.AspNetCore.Routing
RequestDelegate requestDelegate, RequestDelegate requestDelegate,
RoutePattern routePattern, RoutePattern routePattern,
int order, int order,
EndpointMetadataCollection metadata, EndpointMetadataCollection? metadata,
string displayName) string? displayName)
: base(requestDelegate, metadata, displayName) : base(requestDelegate, metadata, displayName)
{ {
if (requestDelegate == null) if (requestDelegate == null)

View File

@ -1,6 +1,7 @@
// 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 Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.AspNetCore.Routing.Patterns;
@ -25,6 +26,11 @@ namespace Microsoft.AspNetCore.Routing
public override Endpoint Build() public override Endpoint Build()
{ {
if (RequestDelegate is null)
{
throw new InvalidOperationException($"{nameof(RequestDelegate)} must be specified to construct a {nameof(RouteEndpoint)}.");
}
var routeEndpoint = new RouteEndpoint( var routeEndpoint = new RouteEndpoint(
RequestDelegate, RequestDelegate,
RoutePattern, RoutePattern,

View File

@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Routing
public class RouteOptions public class RouteOptions
{ {
private IDictionary<string, Type> _constraintTypeMap = GetDefaultConstraintMap(); private IDictionary<string, Type> _constraintTypeMap = GetDefaultConstraintMap();
private ICollection<EndpointDataSource> _endpointDataSources; private ICollection<EndpointDataSource> _endpointDataSources = default!;
/// <summary> /// <summary>
/// Gets a collection of <see cref="EndpointDataSource"/> instances configured with routing. /// Gets a collection of <see cref="EndpointDataSource"/> instances configured with routing.

View File

@ -18,12 +18,12 @@ namespace Microsoft.AspNetCore.Routing
/// ///
/// strings are compared using <see cref="StringComparison.OrdinalIgnoreCase"/>. /// strings are compared using <see cref="StringComparison.OrdinalIgnoreCase"/>.
/// </remarks> /// </remarks>
public class RouteValueEqualityComparer : IEqualityComparer<object> public class RouteValueEqualityComparer : IEqualityComparer<object?>
{ {
public static readonly RouteValueEqualityComparer Default = new RouteValueEqualityComparer(); public static readonly RouteValueEqualityComparer Default = new RouteValueEqualityComparer();
/// <inheritdoc /> /// <inheritdoc />
public new bool Equals(object x, object y) public new bool Equals(object? x, object? y)
{ {
var stringX = x as string ?? Convert.ToString(x, CultureInfo.InvariantCulture); var stringX = x as string ?? Convert.ToString(x, CultureInfo.InvariantCulture);
var stringY = y as string ?? Convert.ToString(y, CultureInfo.InvariantCulture); var stringY = y as string ?? Convert.ToString(y, CultureInfo.InvariantCulture);

View File

@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.Routing
var state = State; var state = State;
IList<OutboundMatchResult> matchResults = null; IList<OutboundMatchResult>? matchResults = null;
if (string.IsNullOrEmpty(address.RouteName)) if (string.IsNullOrEmpty(address.RouteName))
{ {
matchResults = state.AllMatchesLinkGenerationTree.GetMatches( matchResults = state.AllMatchesLinkGenerationTree.GetMatches(
@ -141,8 +141,8 @@ namespace Microsoft.AspNetCore.Routing
private OutboundRouteEntry CreateOutboundRouteEntry( private OutboundRouteEntry CreateOutboundRouteEntry(
RouteEndpoint endpoint, RouteEndpoint endpoint,
IReadOnlyDictionary<string, object> requiredValues, IReadOnlyDictionary<string, object?> requiredValues,
string routeName) string? routeName)
{ {
var entry = new OutboundRouteEntry() var entry = new OutboundRouteEntry()
{ {

View File

@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Routing.Template
throw new ArgumentNullException(nameof(other)); throw new ArgumentNullException(nameof(other));
} }
Constraint = other.Content; Constraint = other.Content!;
} }
/// <summary> /// <summary>

View File

@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Routing.Template
} }
} }
public string TemplateText { get; } public string? TemplateText { get; }
public IList<TemplatePart> Parameters { get; } public IList<TemplatePart> Parameters { get; }

View File

@ -1,8 +1,6 @@
// 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;

View File

@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.Routing.Template
continue; continue;
} }
if (Defaults.TryGetValue(part.Name, out var value)) if (Defaults.TryGetValue(part.Name!, out var value))
{ {
_hasDefaultValue[i] = true; _hasDefaultValue[i] = true;
_defaultValues[i] = value; _defaultValues[i] = value;

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using Microsoft.AspNetCore.Routing.Patterns; using Microsoft.AspNetCore.Routing.Patterns;
@ -32,7 +33,7 @@ namespace Microsoft.AspNetCore.Routing.Template
IsCatchAll = parameter.IsCatchAll; IsCatchAll = parameter.IsCatchAll;
IsOptional = parameter.IsOptional; IsOptional = parameter.IsOptional;
DefaultValue = parameter.Default; DefaultValue = parameter.Default;
InlineConstraints = parameter.ParameterPolicies?.Select(p => new InlineConstraint(p)); InlineConstraints = parameter.ParameterPolicies?.Select(p => new InlineConstraint(p)) ?? Enumerable.Empty<InlineConstraint>();
} }
else if (other.IsSeparator && other is RoutePatternSeparatorPart separator) else if (other.IsSeparator && other is RoutePatternSeparatorPart separator)
{ {
@ -59,8 +60,8 @@ namespace Microsoft.AspNetCore.Routing.Template
string name, string name,
bool isCatchAll, bool isCatchAll,
bool isOptional, bool isOptional,
object defaultValue, object? defaultValue,
IEnumerable<InlineConstraint> inlineConstraints) IEnumerable<InlineConstraint>? inlineConstraints)
{ {
if (name == null) if (name == null)
{ {
@ -83,12 +84,12 @@ namespace Microsoft.AspNetCore.Routing.Template
public bool IsParameter { get; private set; } public bool IsParameter { get; private set; }
public bool IsOptional { get; private set; } public bool IsOptional { get; private set; }
public bool IsOptionalSeperator { get; set; } public bool IsOptionalSeperator { get; set; }
public string Name { get; private set; } public string? Name { get; private set; }
public string Text { get; private set; } public string? Text { get; private set; }
public object DefaultValue { get; private set; } public object? DefaultValue { get; private set; }
public IEnumerable<InlineConstraint> InlineConstraints { get; private set; } public IEnumerable<InlineConstraint> InlineConstraints { get; private set; } = Enumerable.Empty<InlineConstraint>();
internal string DebuggerToString() internal string? DebuggerToString()
{ {
if (IsParameter) if (IsParameter)
{ {
@ -104,11 +105,11 @@ namespace Microsoft.AspNetCore.Routing.Template
{ {
if (IsLiteral && IsOptionalSeperator) if (IsLiteral && IsOptionalSeperator)
{ {
return RoutePatternFactory.SeparatorPart(Text); return RoutePatternFactory.SeparatorPart(Text!);
} }
else if (IsLiteral) else if (IsLiteral)
{ {
return RoutePatternFactory.LiteralPart(Text); return RoutePatternFactory.LiteralPart(Text!);
} }
else else
{ {
@ -119,7 +120,7 @@ namespace Microsoft.AspNetCore.Routing.Template
RoutePatternParameterKind.Standard; RoutePatternParameterKind.Standard;
var constraints = InlineConstraints.Select(c => new RoutePatternParameterPolicyReference(c.Constraint)); var constraints = InlineConstraints.Select(c => new RoutePatternParameterPolicyReference(c.Constraint));
return RoutePatternFactory.ParameterPart(Name, DefaultValue, kind, constraints); return RoutePatternFactory.ParameterPart(Name!, DefaultValue, kind, constraints);
} }
} }
} }

View File

@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Routing.Template
/// <summary> /// <summary>
/// The set of values that will appear in the URL. /// The set of values that will appear in the URL.
/// </summary> /// </summary>
public RouteValueDictionary AcceptedValues { get; set; } public RouteValueDictionary AcceptedValues { get; set; } = default!;
/// <summary> /// <summary>
/// The set of values that that were supplied for URL generation. /// The set of values that that were supplied for URL generation.
@ -24,6 +24,6 @@ namespace Microsoft.AspNetCore.Routing.Template
/// Implicit (ambient) values which are invalidated due to changes in values lexically earlier in the /// Implicit (ambient) values which are invalidated due to changes in values lexically earlier in the
/// route template are excluded from this set. /// route template are excluded from this set.
/// </remarks> /// </remarks>
public RouteValueDictionary CombinedValues { get; set; } public RouteValueDictionary CombinedValues { get; set; } = default!;
} }
} }

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 disable
using System.Diagnostics; using System.Diagnostics;
using Microsoft.AspNetCore.Routing.Template; using Microsoft.AspNetCore.Routing.Template;

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 disable
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNetCore.Routing.Template; using Microsoft.AspNetCore.Routing.Template;

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 disable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;

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 disable
using Microsoft.AspNetCore.Routing.Template; using Microsoft.AspNetCore.Routing.Template;
namespace Microsoft.AspNetCore.Routing.Tree namespace Microsoft.AspNetCore.Routing.Tree

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 disable
using System.Collections.Generic; using System.Collections.Generic;
using Microsoft.AspNetCore.Routing.Template; using Microsoft.AspNetCore.Routing.Template;

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 disable
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;

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 disable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
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 disable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;

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 disable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;

View File

@ -158,7 +158,7 @@ namespace Microsoft.AspNetCore.Routing.Tree
current.Matches.Sort((x, y) => current.Matches.Sort((x, y) =>
{ {
var result = x.Entry.Precedence.CompareTo(y.Entry.Precedence); var result = x.Entry.Precedence.CompareTo(y.Entry.Precedence);
return result == 0 ? x.Entry.RouteTemplate.TemplateText.CompareTo(y.Entry.RouteTemplate.TemplateText) : result; return result == 0 ? x.Entry.RouteTemplate.TemplateText!.CompareTo(y.Entry.RouteTemplate.TemplateText) : result;
}); });
} }