Przeglądaj źródła

Add nullable annotations to Http.Abstractions, Http.Features, Connections.Abstractions (#22337)

* Add nullable annotations to Http.Abstractions, Http.Features, Connections.Abstractions

Co-authored-by: James Newton-King <[email protected]>
Pranav K 5 lat temu
rodzic
commit
f37fa30683
100 zmienionych plików z 824 dodań i 829 usunięć
  1. 1 0
      src/Http/Headers/ref/Microsoft.Net.Http.Headers.csproj
  2. 57 57
      src/Http/Headers/ref/Microsoft.Net.Http.Headers.netcoreapp.cs
  3. 4 3
      src/Http/Headers/src/BaseHeaderParser.cs
  4. 16 17
      src/Http/Headers/src/CacheControlHeaderValue.cs
  5. 19 19
      src/Http/Headers/src/ContentDispositionHeaderValue.cs
  6. 8 7
      src/Http/Headers/src/ContentRangeHeaderValue.cs
  7. 2 4
      src/Http/Headers/src/CookieHeaderParser.cs
  8. 10 10
      src/Http/Headers/src/CookieHeaderValue.cs
  9. 14 13
      src/Http/Headers/src/EntityTagHeaderValue.cs
  10. 3 2
      src/Http/Headers/src/GenericHeaderParser.cs
  11. 3 8
      src/Http/Headers/src/HeaderUtilities.cs
  12. 13 13
      src/Http/Headers/src/HttpHeaderParser.cs
  13. 0 4
      src/Http/Headers/src/HttpRuleParser.cs
  14. 17 16
      src/Http/Headers/src/MediaTypeHeaderValue.cs
  15. 12 8
      src/Http/Headers/src/MediaTypeHeaderValueComparer.cs
  16. 1 0
      src/Http/Headers/src/Microsoft.Net.Http.Headers.csproj
  17. 19 23
      src/Http/Headers/src/NameValueHeaderValue.cs
  18. 2 2
      src/Http/Headers/src/ObjectCollection.cs
  19. 13 12
      src/Http/Headers/src/RangeConditionHeaderValue.cs
  20. 8 7
      src/Http/Headers/src/RangeHeaderValue.cs
  21. 4 5
      src/Http/Headers/src/RangeItemHeaderValue.cs
  22. 14 13
      src/Http/Headers/src/SetCookieHeaderValue.cs
  23. 12 11
      src/Http/Headers/src/StringWithQualityHeaderValue.cs
  24. 3 9
      src/Http/Headers/src/StringWithQualityHeaderValueComparer.cs
  25. 9 11
      src/Http/Headers/test/CacheControlHeaderValueTest.cs
  26. 8 10
      src/Http/Headers/test/ContentDispositionHeaderValueTest.cs
  27. 8 11
      src/Http/Headers/test/ContentRangeHeaderValueTest.cs
  28. 6 6
      src/Http/Headers/test/CookieHeaderValueTest.cs
  29. 2 2
      src/Http/Headers/test/DateParserTest.cs
  30. 12 19
      src/Http/Headers/test/EntityTagHeaderValueTest.cs
  31. 15 22
      src/Http/Headers/test/MediaTypeHeaderValueTest.cs
  32. 1 0
      src/Http/Headers/test/Microsoft.Net.Http.Headers.Tests.csproj
  33. 13 19
      src/Http/Headers/test/NameValueHeaderValueTest.cs
  34. 5 7
      src/Http/Headers/test/RangeConditionHeaderValueTest.cs
  35. 7 9
      src/Http/Headers/test/RangeHeaderValueTest.cs
  36. 1 1
      src/Http/Headers/test/RangeItemHeaderValueTest.cs
  37. 7 9
      src/Http/Headers/test/SetCookieHeaderValueTest.cs
  38. 10 16
      src/Http/Headers/test/StringWithQualityHeaderValueTest.cs
  39. 1 0
      src/Http/Http.Abstractions/ref/Microsoft.AspNetCore.Http.Abstractions.csproj
  40. 47 47
      src/Http/Http.Abstractions/ref/Microsoft.AspNetCore.Http.Abstractions.netcoreapp.cs
  41. 4 4
      src/Http/Http.Abstractions/src/CookieBuilder.cs
  42. 2 2
      src/Http/Http.Abstractions/src/Extensions/EndpointBuilder.cs
  43. 1 1
      src/Http/Http.Abstractions/src/Extensions/MapExtensions.cs
  44. 6 1
      src/Http/Http.Abstractions/src/Extensions/MapMiddleware.cs
  45. 1 1
      src/Http/Http.Abstractions/src/Extensions/MapOptions.cs
  46. 13 3
      src/Http/Http.Abstractions/src/Extensions/MapWhenMiddleware.cs
  47. 4 4
      src/Http/Http.Abstractions/src/Extensions/MapWhenOptions.cs
  48. 3 3
      src/Http/Http.Abstractions/src/Extensions/UseMiddlewareExtensions.cs
  49. 1 1
      src/Http/Http.Abstractions/src/FragmentString.cs
  50. 1 1
      src/Http/Http.Abstractions/src/HostString.cs
  51. 2 2
      src/Http/Http.Abstractions/src/HttpContext.cs
  52. 1 1
      src/Http/Http.Abstractions/src/HttpRequest.cs
  53. 1 5
      src/Http/Http.Abstractions/src/IMiddlewareFactory.cs
  54. 1 1
      src/Http/Http.Abstractions/src/Internal/HeaderSegment.cs
  55. 1 1
      src/Http/Http.Abstractions/src/Internal/HeaderSegmentCollection.cs
  56. 2 4
      src/Http/Http.Abstractions/src/Microsoft.AspNetCore.Http.Abstractions.csproj
  57. 13 13
      src/Http/Http.Abstractions/src/PathString.cs
  58. 17 24
      src/Http/Http.Abstractions/src/QueryString.cs
  59. 2 2
      src/Http/Http.Abstractions/src/Routing/Endpoint.cs
  60. 3 3
      src/Http/Http.Abstractions/src/Routing/EndpointHttpContextExtensions.cs
  61. 5 5
      src/Http/Http.Abstractions/src/Routing/EndpointMetadataCollection.cs
  62. 2 2
      src/Http/Http.Abstractions/src/Routing/IEndpointFeature.cs
  63. 53 46
      src/Http/Http.Abstractions/src/Routing/RouteValueDictionary.cs
  64. 1 1
      src/Http/Http.Abstractions/src/WebSocketManager.cs
  65. 1 1
      src/Http/Http.Abstractions/test/EndpointHttpContextExtensionsTests.cs
  66. 5 5
      src/Http/Http.Abstractions/test/MapPathMiddlewareTests.cs
  67. 7 8
      src/Http/Http.Abstractions/test/MapPredicateMiddlewareTests.cs
  68. 1 0
      src/Http/Http.Abstractions/test/Microsoft.AspNetCore.Http.Abstractions.Tests.csproj
  69. 5 5
      src/Http/Http.Abstractions/test/QueryStringTests.cs
  70. 140 147
      src/Http/Http.Abstractions/test/RouteValueDictionaryTests.cs
  71. 7 7
      src/Http/Http.Abstractions/test/UseMiddlewareTest.cs
  72. 3 2
      src/Http/Http.Abstractions/test/UsePathBaseExtensionsTests.cs
  73. 3 3
      src/Http/Http.Abstractions/test/UseWhenExtensionsTests.cs
  74. 1 0
      src/Http/Http.Features/ref/Microsoft.AspNetCore.Http.Features.csproj
  75. 11 7
      src/Http/Http.Features/ref/Microsoft.AspNetCore.Http.Features.netcoreapp.cs
  76. 5 5
      src/Http/Http.Features/ref/Microsoft.AspNetCore.Http.Features.netstandard2.0.cs
  77. 2 2
      src/Http/Http.Features/src/CookieOptions.cs
  78. 7 5
      src/Http/Http.Features/src/FeatureCollection.cs
  79. 6 3
      src/Http/Http.Features/src/FeatureReference.cs
  80. 7 5
      src/Http/Http.Features/src/FeatureReferences.cs
  81. 1 1
      src/Http/Http.Features/src/IFeatureCollection.cs
  82. 3 1
      src/Http/Http.Features/src/Microsoft.AspNetCore.Http.Features.csproj
  83. 2 2
      src/Http/Http.Features/src/WebSocketAcceptContext.cs
  84. 2 2
      src/Http/Http.Features/test/FeatureCollectionTests.cs
  85. 1 0
      src/Http/Http.Features/test/Microsoft.AspNetCore.Http.Features.Tests.csproj
  86. 4 4
      src/Http/Http/ref/Microsoft.AspNetCore.Http.netcoreapp.cs
  87. 17 0
      src/Http/HttpAbstractions.sln
  88. 1 0
      src/Http/Metadata/ref/Microsoft.AspNetCore.Metadata.csproj
  89. 3 3
      src/Http/Metadata/ref/Microsoft.AspNetCore.Metadata.netcoreapp.cs
  90. 3 3
      src/Http/Metadata/ref/Microsoft.AspNetCore.Metadata.netstandard2.0.cs
  91. 3 3
      src/Http/Metadata/src/IAuthorizeData.cs
  92. 1 0
      src/Http/Metadata/src/Microsoft.AspNetCore.Metadata.csproj
  93. 1 0
      src/Http/Routing.Abstractions/ref/Microsoft.AspNetCore.Routing.Abstractions.csproj
  94. 8 8
      src/Http/Routing.Abstractions/ref/Microsoft.AspNetCore.Routing.Abstractions.netcoreapp.cs
  95. 8 8
      src/Http/Routing.Abstractions/src/LinkGenerator.cs
  96. 2 1
      src/Http/Routing.Abstractions/src/Microsoft.AspNetCore.Routing.Abstractions.csproj
  97. 2 2
      src/Http/Routing.Abstractions/src/RouteContext.cs
  98. 1 1
      src/Http/Routing.Abstractions/src/RoutingHttpContextExtensions.cs
  99. 2 2
      src/Http/Routing.Abstractions/src/VirtualPathContext.cs
  100. 1 0
      src/Http/Routing/ref/Microsoft.AspNetCore.Routing.csproj

+ 1 - 0
src/Http/Headers/ref/Microsoft.Net.Http.Headers.csproj

@@ -2,6 +2,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <TargetFrameworks>$(DefaultNetCoreTargetFramework)</TargetFrameworks>
+    <Nullable>annotations</Nullable>
   </PropertyGroup>
   <ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'">
     <Compile Include="Microsoft.Net.Http.Headers.netcoreapp.cs" />

+ 57 - 57
src/Http/Headers/ref/Microsoft.Net.Http.Headers.netcoreapp.cs

@@ -34,11 +34,11 @@ namespace Microsoft.Net.Http.Headers
         public bool ProxyRevalidate { get { throw null; } set { } }
         public bool Public { get { throw null; } set { } }
         public System.TimeSpan? SharedMaxAge { get { throw null; } set { } }
-        public override bool Equals(object obj) { throw null; }
+        public override bool Equals(object? obj) { throw null; }
         public override int GetHashCode() { throw null; }
         public static Microsoft.Net.Http.Headers.CacheControlHeaderValue Parse(Microsoft.Extensions.Primitives.StringSegment input) { throw null; }
         public override string ToString() { throw null; }
-        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, out Microsoft.Net.Http.Headers.CacheControlHeaderValue parsedValue) { throw null; }
+        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out Microsoft.Net.Http.Headers.CacheControlHeaderValue? parsedValue) { throw null; }
     }
     public partial class ContentDispositionHeaderValue
     {
@@ -52,13 +52,13 @@ namespace Microsoft.Net.Http.Headers
         public System.Collections.Generic.IList<Microsoft.Net.Http.Headers.NameValueHeaderValue> Parameters { get { throw null; } }
         public System.DateTimeOffset? ReadDate { get { throw null; } set { } }
         public long? Size { get { throw null; } set { } }
-        public override bool Equals(object obj) { throw null; }
+        public override bool Equals(object? obj) { throw null; }
         public override int GetHashCode() { throw null; }
         public static Microsoft.Net.Http.Headers.ContentDispositionHeaderValue Parse(Microsoft.Extensions.Primitives.StringSegment input) { throw null; }
         public void SetHttpFileName(Microsoft.Extensions.Primitives.StringSegment fileName) { }
         public void SetMimeFileName(Microsoft.Extensions.Primitives.StringSegment fileName) { }
         public override string ToString() { throw null; }
-        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, out Microsoft.Net.Http.Headers.ContentDispositionHeaderValue parsedValue) { throw null; }
+        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out Microsoft.Net.Http.Headers.ContentDispositionHeaderValue? parsedValue) { throw null; }
     }
     public static partial class ContentDispositionHeaderValueIdentityExtensions
     {
@@ -76,11 +76,11 @@ namespace Microsoft.Net.Http.Headers
         public long? Length { get { throw null; } }
         public long? To { get { throw null; } }
         public Microsoft.Extensions.Primitives.StringSegment Unit { get { throw null; } set { } }
-        public override bool Equals(object obj) { throw null; }
+        public override bool Equals(object? obj) { throw null; }
         public override int GetHashCode() { throw null; }
         public static Microsoft.Net.Http.Headers.ContentRangeHeaderValue Parse(Microsoft.Extensions.Primitives.StringSegment input) { throw null; }
         public override string ToString() { throw null; }
-        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, out Microsoft.Net.Http.Headers.ContentRangeHeaderValue parsedValue) { throw null; }
+        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out Microsoft.Net.Http.Headers.ContentRangeHeaderValue parsedValue) { throw null; }
     }
     public partial class CookieHeaderValue
     {
@@ -88,15 +88,15 @@ namespace Microsoft.Net.Http.Headers
         public CookieHeaderValue(Microsoft.Extensions.Primitives.StringSegment name, Microsoft.Extensions.Primitives.StringSegment value) { }
         public Microsoft.Extensions.Primitives.StringSegment Name { get { throw null; } set { } }
         public Microsoft.Extensions.Primitives.StringSegment Value { get { throw null; } set { } }
-        public override bool Equals(object obj) { throw null; }
+        public override bool Equals(object? obj) { throw null; }
         public override int GetHashCode() { throw null; }
         public static Microsoft.Net.Http.Headers.CookieHeaderValue Parse(Microsoft.Extensions.Primitives.StringSegment input) { throw null; }
-        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.CookieHeaderValue> ParseList(System.Collections.Generic.IList<string> inputs) { throw null; }
-        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.CookieHeaderValue> ParseStrictList(System.Collections.Generic.IList<string> inputs) { throw null; }
+        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.CookieHeaderValue> ParseList(System.Collections.Generic.IList<string>? inputs) { throw null; }
+        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.CookieHeaderValue> ParseStrictList(System.Collections.Generic.IList<string>? inputs) { throw null; }
         public override string ToString() { throw null; }
-        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, out Microsoft.Net.Http.Headers.CookieHeaderValue parsedValue) { throw null; }
-        public static bool TryParseList(System.Collections.Generic.IList<string> inputs, out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.CookieHeaderValue> parsedValues) { throw null; }
-        public static bool TryParseStrictList(System.Collections.Generic.IList<string> inputs, out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.CookieHeaderValue> parsedValues) { throw null; }
+        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out Microsoft.Net.Http.Headers.CookieHeaderValue? parsedValue) { throw null; }
+        public static bool TryParseList(System.Collections.Generic.IList<string>? inputs, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.CookieHeaderValue>? parsedValues) { throw null; }
+        public static bool TryParseStrictList(System.Collections.Generic.IList<string>? inputs, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.CookieHeaderValue>? parsedValues) { throw null; }
     }
     public partial class EntityTagHeaderValue
     {
@@ -105,16 +105,16 @@ namespace Microsoft.Net.Http.Headers
         public static Microsoft.Net.Http.Headers.EntityTagHeaderValue Any { get { throw null; } }
         public bool IsWeak { get { throw null; } }
         public Microsoft.Extensions.Primitives.StringSegment Tag { get { throw null; } }
-        public bool Compare(Microsoft.Net.Http.Headers.EntityTagHeaderValue other, bool useStrongComparison) { throw null; }
-        public override bool Equals(object obj) { throw null; }
+        public bool Compare(Microsoft.Net.Http.Headers.EntityTagHeaderValue? other, bool useStrongComparison) { throw null; }
+        public override bool Equals(object? obj) { throw null; }
         public override int GetHashCode() { throw null; }
         public static Microsoft.Net.Http.Headers.EntityTagHeaderValue Parse(Microsoft.Extensions.Primitives.StringSegment input) { throw null; }
-        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.EntityTagHeaderValue> ParseList(System.Collections.Generic.IList<string> inputs) { throw null; }
-        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.EntityTagHeaderValue> ParseStrictList(System.Collections.Generic.IList<string> inputs) { throw null; }
+        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.EntityTagHeaderValue> ParseList(System.Collections.Generic.IList<string>? inputs) { throw null; }
+        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.EntityTagHeaderValue> ParseStrictList(System.Collections.Generic.IList<string>? inputs) { throw null; }
         public override string ToString() { throw null; }
-        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, out Microsoft.Net.Http.Headers.EntityTagHeaderValue parsedValue) { throw null; }
-        public static bool TryParseList(System.Collections.Generic.IList<string> inputs, out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.EntityTagHeaderValue> parsedValues) { throw null; }
-        public static bool TryParseStrictList(System.Collections.Generic.IList<string> inputs, out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.EntityTagHeaderValue> parsedValues) { throw null; }
+        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out Microsoft.Net.Http.Headers.EntityTagHeaderValue parsedValue) { throw null; }
+        public static bool TryParseList(System.Collections.Generic.IList<string>? inputs, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.EntityTagHeaderValue>? parsedValues) { throw null; }
+        public static bool TryParseStrictList(System.Collections.Generic.IList<string>? inputs, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.EntityTagHeaderValue>? parsedValues) { throw null; }
     }
     public static partial class HeaderNames
     {
@@ -228,7 +228,7 @@ namespace Microsoft.Net.Http.Headers
         public MediaTypeHeaderValue(Microsoft.Extensions.Primitives.StringSegment mediaType, double quality) { }
         public Microsoft.Extensions.Primitives.StringSegment Boundary { get { throw null; } set { } }
         public Microsoft.Extensions.Primitives.StringSegment Charset { get { throw null; } set { } }
-        public System.Text.Encoding Encoding { get { throw null; } set { } }
+        public System.Text.Encoding? Encoding { get { throw null; } set { } }
         public System.Collections.Generic.IEnumerable<Microsoft.Extensions.Primitives.StringSegment> Facets { get { throw null; } }
         public bool IsReadOnly { get { throw null; } }
         public bool MatchesAllSubTypes { get { throw null; } }
@@ -243,22 +243,22 @@ namespace Microsoft.Net.Http.Headers
         public Microsoft.Extensions.Primitives.StringSegment Type { get { throw null; } }
         public Microsoft.Net.Http.Headers.MediaTypeHeaderValue Copy() { throw null; }
         public Microsoft.Net.Http.Headers.MediaTypeHeaderValue CopyAsReadOnly() { throw null; }
-        public override bool Equals(object obj) { throw null; }
+        public override bool Equals(object? obj) { throw null; }
         public override int GetHashCode() { throw null; }
         public bool IsSubsetOf(Microsoft.Net.Http.Headers.MediaTypeHeaderValue otherMediaType) { throw null; }
         public static Microsoft.Net.Http.Headers.MediaTypeHeaderValue Parse(Microsoft.Extensions.Primitives.StringSegment input) { throw null; }
-        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.MediaTypeHeaderValue> ParseList(System.Collections.Generic.IList<string> inputs) { throw null; }
-        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.MediaTypeHeaderValue> ParseStrictList(System.Collections.Generic.IList<string> inputs) { throw null; }
+        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.MediaTypeHeaderValue> ParseList(System.Collections.Generic.IList<string>? inputs) { throw null; }
+        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.MediaTypeHeaderValue> ParseStrictList(System.Collections.Generic.IList<string>? inputs) { throw null; }
         public override string ToString() { throw null; }
-        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, out Microsoft.Net.Http.Headers.MediaTypeHeaderValue parsedValue) { throw null; }
-        public static bool TryParseList(System.Collections.Generic.IList<string> inputs, out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.MediaTypeHeaderValue> parsedValues) { throw null; }
-        public static bool TryParseStrictList(System.Collections.Generic.IList<string> inputs, out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.MediaTypeHeaderValue> parsedValues) { throw null; }
+        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out Microsoft.Net.Http.Headers.MediaTypeHeaderValue? parsedValue) { throw null; }
+        public static bool TryParseList(System.Collections.Generic.IList<string>? inputs, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.MediaTypeHeaderValue>? parsedValues) { throw null; }
+        public static bool TryParseStrictList(System.Collections.Generic.IList<string>? inputs, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.MediaTypeHeaderValue>? parsedValues) { throw null; }
     }
     public partial class MediaTypeHeaderValueComparer : System.Collections.Generic.IComparer<Microsoft.Net.Http.Headers.MediaTypeHeaderValue>
     {
         internal MediaTypeHeaderValueComparer() { }
-        public static Microsoft.Net.Http.Headers.MediaTypeHeaderValueComparer QualityComparer { get { throw null; } }
-        public int Compare(Microsoft.Net.Http.Headers.MediaTypeHeaderValue mediaType1, Microsoft.Net.Http.Headers.MediaTypeHeaderValue mediaType2) { throw null; }
+        public static Microsoft.Net.Http.Headers.MediaTypeHeaderValueComparer QualityComparer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
+        public int Compare(Microsoft.Net.Http.Headers.MediaTypeHeaderValue? mediaType1, Microsoft.Net.Http.Headers.MediaTypeHeaderValue? mediaType2) { throw null; }
     }
     public partial class NameValueHeaderValue
     {
@@ -269,31 +269,31 @@ namespace Microsoft.Net.Http.Headers
         public Microsoft.Extensions.Primitives.StringSegment Value { get { throw null; } set { } }
         public Microsoft.Net.Http.Headers.NameValueHeaderValue Copy() { throw null; }
         public Microsoft.Net.Http.Headers.NameValueHeaderValue CopyAsReadOnly() { throw null; }
-        public override bool Equals(object obj) { throw null; }
-        public static Microsoft.Net.Http.Headers.NameValueHeaderValue Find(System.Collections.Generic.IList<Microsoft.Net.Http.Headers.NameValueHeaderValue> values, Microsoft.Extensions.Primitives.StringSegment name) { throw null; }
+        public override bool Equals(object? obj) { throw null; }
+        public static Microsoft.Net.Http.Headers.NameValueHeaderValue? Find(System.Collections.Generic.IList<Microsoft.Net.Http.Headers.NameValueHeaderValue>? values, Microsoft.Extensions.Primitives.StringSegment name) { throw null; }
         public override int GetHashCode() { throw null; }
         public Microsoft.Extensions.Primitives.StringSegment GetUnescapedValue() { throw null; }
         public static Microsoft.Net.Http.Headers.NameValueHeaderValue Parse(Microsoft.Extensions.Primitives.StringSegment input) { throw null; }
-        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.NameValueHeaderValue> ParseList(System.Collections.Generic.IList<string> input) { throw null; }
-        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.NameValueHeaderValue> ParseStrictList(System.Collections.Generic.IList<string> input) { throw null; }
+        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.NameValueHeaderValue> ParseList(System.Collections.Generic.IList<string>? input) { throw null; }
+        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.NameValueHeaderValue> ParseStrictList(System.Collections.Generic.IList<string>? input) { throw null; }
         public void SetAndEscapeValue(Microsoft.Extensions.Primitives.StringSegment value) { }
         public override string ToString() { throw null; }
-        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, out Microsoft.Net.Http.Headers.NameValueHeaderValue parsedValue) { throw null; }
-        public static bool TryParseList(System.Collections.Generic.IList<string> input, out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.NameValueHeaderValue> parsedValues) { throw null; }
-        public static bool TryParseStrictList(System.Collections.Generic.IList<string> input, out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.NameValueHeaderValue> parsedValues) { throw null; }
+        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out Microsoft.Net.Http.Headers.NameValueHeaderValue? parsedValue) { throw null; }
+        public static bool TryParseList(System.Collections.Generic.IList<string>? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.NameValueHeaderValue>? parsedValues) { throw null; }
+        public static bool TryParseStrictList(System.Collections.Generic.IList<string>? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.NameValueHeaderValue>? parsedValues) { throw null; }
     }
     public partial class RangeConditionHeaderValue
     {
-        public RangeConditionHeaderValue(Microsoft.Net.Http.Headers.EntityTagHeaderValue entityTag) { }
+        public RangeConditionHeaderValue(Microsoft.Net.Http.Headers.EntityTagHeaderValue? entityTag) { }
         public RangeConditionHeaderValue(System.DateTimeOffset lastModified) { }
-        public RangeConditionHeaderValue(string entityTag) { }
-        public Microsoft.Net.Http.Headers.EntityTagHeaderValue EntityTag { get { throw null; } }
+        public RangeConditionHeaderValue(string? entityTag) { }
+        public Microsoft.Net.Http.Headers.EntityTagHeaderValue? EntityTag { get { throw null; } }
         public System.DateTimeOffset? LastModified { get { throw null; } }
-        public override bool Equals(object obj) { throw null; }
+        public override bool Equals(object? obj) { throw null; }
         public override int GetHashCode() { throw null; }
         public static Microsoft.Net.Http.Headers.RangeConditionHeaderValue Parse(Microsoft.Extensions.Primitives.StringSegment input) { throw null; }
         public override string ToString() { throw null; }
-        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, out Microsoft.Net.Http.Headers.RangeConditionHeaderValue parsedValue) { throw null; }
+        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out Microsoft.Net.Http.Headers.RangeConditionHeaderValue? parsedValue) { throw null; }
     }
     public partial class RangeHeaderValue
     {
@@ -301,18 +301,18 @@ namespace Microsoft.Net.Http.Headers
         public RangeHeaderValue(long? from, long? to) { }
         public System.Collections.Generic.ICollection<Microsoft.Net.Http.Headers.RangeItemHeaderValue> Ranges { get { throw null; } }
         public Microsoft.Extensions.Primitives.StringSegment Unit { get { throw null; } set { } }
-        public override bool Equals(object obj) { throw null; }
+        public override bool Equals(object? obj) { throw null; }
         public override int GetHashCode() { throw null; }
         public static Microsoft.Net.Http.Headers.RangeHeaderValue Parse(Microsoft.Extensions.Primitives.StringSegment input) { throw null; }
         public override string ToString() { throw null; }
-        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, out Microsoft.Net.Http.Headers.RangeHeaderValue parsedValue) { throw null; }
+        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out Microsoft.Net.Http.Headers.RangeHeaderValue parsedValue) { throw null; }
     }
     public partial class RangeItemHeaderValue
     {
         public RangeItemHeaderValue(long? from, long? to) { }
         public long? From { get { throw null; } }
         public long? To { get { throw null; } }
-        public override bool Equals(object obj) { throw null; }
+        public override bool Equals(object? obj) { throw null; }
         public override int GetHashCode() { throw null; }
         public override string ToString() { throw null; }
     }
@@ -337,15 +337,15 @@ namespace Microsoft.Net.Http.Headers
         public bool Secure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public Microsoft.Extensions.Primitives.StringSegment Value { get { throw null; } set { } }
         public void AppendToStringBuilder(System.Text.StringBuilder builder) { }
-        public override bool Equals(object obj) { throw null; }
+        public override bool Equals(object? obj) { throw null; }
         public override int GetHashCode() { throw null; }
         public static Microsoft.Net.Http.Headers.SetCookieHeaderValue Parse(Microsoft.Extensions.Primitives.StringSegment input) { throw null; }
-        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.SetCookieHeaderValue> ParseList(System.Collections.Generic.IList<string> inputs) { throw null; }
-        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.SetCookieHeaderValue> ParseStrictList(System.Collections.Generic.IList<string> inputs) { throw null; }
+        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.SetCookieHeaderValue> ParseList(System.Collections.Generic.IList<string>? inputs) { throw null; }
+        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.SetCookieHeaderValue> ParseStrictList(System.Collections.Generic.IList<string>? inputs) { throw null; }
         public override string ToString() { throw null; }
-        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, out Microsoft.Net.Http.Headers.SetCookieHeaderValue parsedValue) { throw null; }
-        public static bool TryParseList(System.Collections.Generic.IList<string> inputs, out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.SetCookieHeaderValue> parsedValues) { throw null; }
-        public static bool TryParseStrictList(System.Collections.Generic.IList<string> inputs, out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.SetCookieHeaderValue> parsedValues) { throw null; }
+        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out Microsoft.Net.Http.Headers.SetCookieHeaderValue? parsedValue) { throw null; }
+        public static bool TryParseList(System.Collections.Generic.IList<string>? inputs, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.SetCookieHeaderValue>? parsedValues) { throw null; }
+        public static bool TryParseStrictList(System.Collections.Generic.IList<string>? inputs, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.SetCookieHeaderValue>? parsedValues) { throw null; }
     }
     public partial class StringWithQualityHeaderValue
     {
@@ -353,20 +353,20 @@ namespace Microsoft.Net.Http.Headers
         public StringWithQualityHeaderValue(Microsoft.Extensions.Primitives.StringSegment value, double quality) { }
         public double? Quality { get { throw null; } }
         public Microsoft.Extensions.Primitives.StringSegment Value { get { throw null; } }
-        public override bool Equals(object obj) { throw null; }
+        public override bool Equals(object? obj) { throw null; }
         public override int GetHashCode() { throw null; }
         public static Microsoft.Net.Http.Headers.StringWithQualityHeaderValue Parse(Microsoft.Extensions.Primitives.StringSegment input) { throw null; }
-        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.StringWithQualityHeaderValue> ParseList(System.Collections.Generic.IList<string> input) { throw null; }
-        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.StringWithQualityHeaderValue> ParseStrictList(System.Collections.Generic.IList<string> input) { throw null; }
+        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.StringWithQualityHeaderValue> ParseList(System.Collections.Generic.IList<string>? input) { throw null; }
+        public static System.Collections.Generic.IList<Microsoft.Net.Http.Headers.StringWithQualityHeaderValue> ParseStrictList(System.Collections.Generic.IList<string>? input) { throw null; }
         public override string ToString() { throw null; }
-        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, out Microsoft.Net.Http.Headers.StringWithQualityHeaderValue parsedValue) { throw null; }
-        public static bool TryParseList(System.Collections.Generic.IList<string> input, out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.StringWithQualityHeaderValue> parsedValues) { throw null; }
-        public static bool TryParseStrictList(System.Collections.Generic.IList<string> input, out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.StringWithQualityHeaderValue> parsedValues) { throw null; }
+        public static bool TryParse(Microsoft.Extensions.Primitives.StringSegment input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out Microsoft.Net.Http.Headers.StringWithQualityHeaderValue parsedValue) { throw null; }
+        public static bool TryParseList(System.Collections.Generic.IList<string>? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.StringWithQualityHeaderValue>? parsedValues) { throw null; }
+        public static bool TryParseStrictList(System.Collections.Generic.IList<string>? input, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out System.Collections.Generic.IList<Microsoft.Net.Http.Headers.StringWithQualityHeaderValue>? parsedValues) { throw null; }
     }
     public partial class StringWithQualityHeaderValueComparer : System.Collections.Generic.IComparer<Microsoft.Net.Http.Headers.StringWithQualityHeaderValue>
     {
         internal StringWithQualityHeaderValueComparer() { }
-        public static Microsoft.Net.Http.Headers.StringWithQualityHeaderValueComparer QualityComparer { get { throw null; } }
-        public int Compare(Microsoft.Net.Http.Headers.StringWithQualityHeaderValue stringWithQuality1, Microsoft.Net.Http.Headers.StringWithQualityHeaderValue stringWithQuality2) { throw null; }
+        public static Microsoft.Net.Http.Headers.StringWithQualityHeaderValueComparer QualityComparer { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
+        public int Compare(Microsoft.Net.Http.Headers.StringWithQualityHeaderValue? stringWithQuality1, Microsoft.Net.Http.Headers.StringWithQualityHeaderValue? stringWithQuality2) { throw null; }
     }
 }

+ 4 - 3
src/Http/Headers/src/BaseHeaderParser.cs

@@ -1,6 +1,7 @@
 // Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
+using System.Diagnostics.CodeAnalysis;
 using Microsoft.Extensions.Primitives;
 
 namespace Microsoft.Net.Http.Headers
@@ -12,11 +13,11 @@ namespace Microsoft.Net.Http.Headers
         {
         }
 
-        protected abstract int GetParsedValueLength(StringSegment value, int startIndex, out T parsedValue);
+        protected abstract int GetParsedValueLength(StringSegment value, int startIndex, [MaybeNull] out T parsedValue);
 
-        public sealed override bool TryParseValue(StringSegment value, ref int index, out T parsedValue)
+        public sealed override bool TryParseValue(StringSegment value, ref int index, [MaybeNull] out T parsedValue)
         {
-            parsedValue = default(T);
+            parsedValue = default;
 
             // If multiple values are supported (i.e. list of values), then accept an empty string: The header may
             // be added multiple times to the request/response message. E.g.

+ 16 - 17
src/Http/Headers/src/CacheControlHeaderValue.cs

@@ -3,6 +3,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Diagnostics.Contracts;
 using System.Globalization;
 using System.Text;
@@ -31,12 +32,12 @@ namespace Microsoft.Net.Http.Headers
         // Cache-Control headers, only one instance of CacheControlHeaderValue is created (if all headers contain valid
         // values, otherwise we may have multiple strings containing the invalid values).
         private static readonly HttpHeaderParser<CacheControlHeaderValue> Parser
-            = new GenericHeaderParser<CacheControlHeaderValue>(true, GetCacheControlLength);
+            = new GenericHeaderParser<CacheControlHeaderValue>(true, GetCacheControlLength!);
 
         private static readonly Action<StringSegment> CheckIsValidTokenAction = CheckIsValidToken;
 
         private bool _noCache;
-        private ICollection<StringSegment> _noCacheHeaders;
+        private ICollection<StringSegment>? _noCacheHeaders;
         private bool _noStore;
         private TimeSpan? _maxAge;
         private TimeSpan? _sharedMaxAge;
@@ -47,10 +48,10 @@ namespace Microsoft.Net.Http.Headers
         private bool _onlyIfCached;
         private bool _public;
         private bool _private;
-        private ICollection<StringSegment> _privateHeaders;
+        private ICollection<StringSegment>? _privateHeaders;
         private bool _mustRevalidate;
         private bool _proxyRevalidate;
-        private IList<NameValueHeaderValue> _extensions;
+        private IList<NameValueHeaderValue>? _extensions;
 
         public CacheControlHeaderValue()
         {
@@ -240,7 +241,7 @@ namespace Microsoft.Net.Http.Headers
             return sb.ToString();
         }
 
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             var other = obj as CacheControlHeaderValue;
 
@@ -325,7 +326,7 @@ namespace Microsoft.Net.Http.Headers
 
         public static CacheControlHeaderValue Parse(StringSegment input)
         {
-            int index = 0;
+            var index = 0;
             // Cache-Control is unusual because there are no required values so the parser will succeed for an empty string, but still return null.
             var result = Parser.ParseValue(input, ref index);
             if (result == null)
@@ -335,9 +336,9 @@ namespace Microsoft.Net.Http.Headers
             return result;
         }
 
-        public static bool TryParse(StringSegment input, out CacheControlHeaderValue parsedValue)
+        public static bool TryParse(StringSegment input, [NotNullWhen(true)] out CacheControlHeaderValue? parsedValue)
         {
-            int index = 0;
+            var index = 0;
             // Cache-Control is unusual because there are no required values so the parser will succeed for an empty string, but still return null.
             if (Parser.TryParseValue(input, ref index, out parsedValue) && parsedValue != null)
             {
@@ -347,7 +348,7 @@ namespace Microsoft.Net.Http.Headers
             return false;
         }
 
-        private static int GetCacheControlLength(StringSegment input, int startIndex, out CacheControlHeaderValue parsedValue)
+        private static int GetCacheControlLength(StringSegment input, int startIndex, out CacheControlHeaderValue? parsedValue)
         {
             Contract.Requires(startIndex >= 0);
 
@@ -361,16 +362,18 @@ namespace Microsoft.Net.Http.Headers
             // Cache-Control header consists of a list of name/value pairs, where the value is optional. So use an
             // instance of NameValueHeaderParser to parse the string.
             var current = startIndex;
-            NameValueHeaderValue nameValue = null;
             var nameValueList = new List<NameValueHeaderValue>();
             while (current < input.Length)
             {
-                if (!NameValueHeaderValue.MultipleValueParser.TryParseValue(input, ref current, out nameValue))
+                if (!NameValueHeaderValue.MultipleValueParser.TryParseValue(input, ref current, out var nameValue))
                 {
                     return 0;
                 }
 
-                nameValueList.Add(nameValue);
+                if (nameValue != null)
+                {
+                    nameValueList.Add(nameValue);
+                }
             }
 
             // If we get here, we were able to successfully parse the string as list of name/value pairs. Now analyze
@@ -539,10 +542,8 @@ namespace Microsoft.Net.Http.Headers
         private static bool TrySetOptionalTokenList(
             NameValueHeaderValue nameValue,
             ref bool boolField,
-            ref ICollection<StringSegment> destination)
+            ref ICollection<StringSegment>? destination)
         {
-            Contract.Requires(nameValue != null);
-
             if (nameValue.Value == null)
             {
                 boolField = true;
@@ -603,8 +604,6 @@ namespace Microsoft.Net.Http.Headers
 
         private static bool TrySetTimeSpan(NameValueHeaderValue nameValue, ref TimeSpan? timeSpan)
         {
-            Contract.Requires(nameValue != null);
-
             if (nameValue.Value == null)
             {
                 return false;

+ 19 - 19
src/Http/Headers/src/ContentDispositionHeaderValue.cs

@@ -4,6 +4,7 @@
 using System;
 using System.Buffers;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Diagnostics.Contracts;
 using System.Globalization;
 using System.Linq;
@@ -26,10 +27,10 @@ namespace Microsoft.Net.Http.Headers
         private static readonly char[] SingleQuote = new char[] { '\'' };
 
         private static readonly HttpHeaderParser<ContentDispositionHeaderValue> Parser
-            = new GenericHeaderParser<ContentDispositionHeaderValue>(false, GetDispositionTypeLength);
+            = new GenericHeaderParser<ContentDispositionHeaderValue>(false, GetDispositionTypeLength!);
 
         // Use list instead of dictionary since we may have multiple parameters with the same name.
-        private ObjectCollection<NameValueHeaderValue> _parameters;
+        private ObjectCollection<NameValueHeaderValue>? _parameters;
         private StringSegment _dispositionType;
 
         private ContentDispositionHeaderValue()
@@ -109,11 +110,10 @@ namespace Microsoft.Net.Http.Headers
             get
             {
                 var sizeParameter = NameValueHeaderValue.Find(_parameters, SizeString);
-                long value;
                 if (sizeParameter != null)
                 {
                     var sizeString = sizeParameter.Value;
-                    if (HeaderUtilities.TryParseNonNegativeInt64(sizeString, out value))
+                    if (HeaderUtilities.TryParseNonNegativeInt64(sizeString, out var value))
                     {
                         return value;
                     }
@@ -128,7 +128,7 @@ namespace Microsoft.Net.Http.Headers
                     // Remove parameter
                     if (sizeParameter != null)
                     {
-                        _parameters.Remove(sizeParameter);
+                        _parameters!.Remove(sizeParameter);
                     }
                 }
                 else if (value < 0)
@@ -141,8 +141,8 @@ namespace Microsoft.Net.Http.Headers
                 }
                 else
                 {
-                    string sizeString = value.GetValueOrDefault().ToString(CultureInfo.InvariantCulture);
-                    _parameters.Add(new NameValueHeaderValue(SizeString, sizeString));
+                    var sizeString = value.GetValueOrDefault().ToString(CultureInfo.InvariantCulture);
+                    Parameters.Add(new NameValueHeaderValue(SizeString, sizeString));
                 }
             }
         }
@@ -180,7 +180,7 @@ namespace Microsoft.Net.Http.Headers
             return _dispositionType + NameValueHeaderValue.ToString(_parameters, ';', true);
         }
 
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             var other = obj as ContentDispositionHeaderValue;
 
@@ -202,16 +202,16 @@ namespace Microsoft.Net.Http.Headers
         public static ContentDispositionHeaderValue Parse(StringSegment input)
         {
             var index = 0;
-            return Parser.ParseValue(input, ref index);
+            return Parser.ParseValue(input, ref index)!;
         }
 
-        public static bool TryParse(StringSegment input, out ContentDispositionHeaderValue parsedValue)
+        public static bool TryParse(StringSegment input, [NotNullWhen(true)] out ContentDispositionHeaderValue? parsedValue)
         {
             var index = 0;
-            return Parser.TryParseValue(input, ref index, out parsedValue);
+            return Parser.TryParseValue(input, ref index, out parsedValue!);
         }
 
-        private static int GetDispositionTypeLength(StringSegment input, int startIndex, out ContentDispositionHeaderValue parsedValue)
+        private static int GetDispositionTypeLength(StringSegment input, int startIndex, out ContentDispositionHeaderValue? parsedValue)
         {
             Contract.Requires(startIndex >= 0);
 
@@ -253,7 +253,7 @@ namespace Microsoft.Net.Http.Headers
 
         private static int GetDispositionTypeExpressionLength(StringSegment input, int startIndex, out StringSegment dispositionType)
         {
-            Contract.Requires((input != null) && (input.Length > 0) && (startIndex < input.Length));
+            Contract.Requires((input.Length > 0) && (startIndex < input.Length));
 
             // This method just parses the disposition type string, it does not parse parameters.
             dispositionType = null;
@@ -318,7 +318,7 @@ namespace Microsoft.Net.Http.Headers
                 // Remove parameter
                 if (dateParameter != null)
                 {
-                    _parameters.Remove(dateParameter);
+                    _parameters!.Remove(dateParameter);
                 }
             }
             else
@@ -343,7 +343,7 @@ namespace Microsoft.Net.Http.Headers
             var nameParameter = NameValueHeaderValue.Find(_parameters, parameter);
             if (nameParameter != null)
             {
-                string result;
+                string? result;
                 // filename*=utf-8'lang'%7FMyString
                 if (parameter.EndsWith("*", StringComparison.Ordinal))
                 {
@@ -375,7 +375,7 @@ namespace Microsoft.Net.Http.Headers
                 // Remove parameter
                 if (nameParameter != null)
                 {
-                    _parameters.Remove(nameParameter);
+                    _parameters!.Remove(nameParameter);
                 }
             }
             else
@@ -497,7 +497,7 @@ namespace Microsoft.Net.Http.Headers
         }
 
         // Attempt to decode MIME encoded strings
-        private bool TryDecodeMime(StringSegment input, out string output)
+        private bool TryDecodeMime(StringSegment input, [NotNullWhen(true)] out string? output)
         {
             Contract.Assert(input != null);
 
@@ -582,7 +582,7 @@ namespace Microsoft.Net.Http.Headers
 
         // Attempt to decode using RFC 5987 encoding.
         // encoding'language'my%20string
-        private bool TryDecode5987(StringSegment input, out string output)
+        private bool TryDecode5987(StringSegment input, [NotNullWhen(true)] out string? output)
         {
             output = null;
 
@@ -593,7 +593,7 @@ namespace Microsoft.Net.Http.Headers
             }
 
             var decoded = new StringBuilder();
-            byte[] unescapedBytes = null;
+            byte[]? unescapedBytes = null;
             try
             {
                 var encoding = Encoding.GetEncoding(parts[0].ToString());

+ 8 - 7
src/Http/Headers/src/ContentRangeHeaderValue.cs

@@ -2,6 +2,7 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System;
+using System.Diagnostics.CodeAnalysis;
 using System.Diagnostics.Contracts;
 using System.Globalization;
 using System.Text;
@@ -12,7 +13,7 @@ namespace Microsoft.Net.Http.Headers
     public class ContentRangeHeaderValue
     {
         private static readonly HttpHeaderParser<ContentRangeHeaderValue> Parser
-            = new GenericHeaderParser<ContentRangeHeaderValue>(false, GetContentRangeLength);
+            = new GenericHeaderParser<ContentRangeHeaderValue>(false, GetContentRangeLength!);
 
         private StringSegment _unit;
         private long? _from;
@@ -113,7 +114,7 @@ namespace Microsoft.Net.Http.Headers
             get { return _from != null; }
         }
 
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             var other = obj as ContentRangeHeaderValue;
 
@@ -176,16 +177,16 @@ namespace Microsoft.Net.Http.Headers
         public static ContentRangeHeaderValue Parse(StringSegment input)
         {
             var index = 0;
-            return Parser.ParseValue(input, ref index);
+            return Parser.ParseValue(input, ref index)!;
         }
 
-        public static bool TryParse(StringSegment input, out ContentRangeHeaderValue parsedValue)
+        public static bool TryParse(StringSegment input, [NotNullWhen(true)] out ContentRangeHeaderValue parsedValue)
         {
             var index = 0;
-            return Parser.TryParseValue(input, ref index, out parsedValue);
+            return Parser.TryParseValue(input, ref index, out parsedValue!);
         }
 
-        private static int GetContentRangeLength(StringSegment input, int startIndex, out ContentRangeHeaderValue parsedValue)
+        private static int GetContentRangeLength(StringSegment input, int startIndex, out ContentRangeHeaderValue? parsedValue)
         {
             Contract.Requires(startIndex >= 0);
 
@@ -351,7 +352,7 @@ namespace Microsoft.Net.Http.Headers
             int toLength,
             int lengthStartIndex,
             int lengthLength,
-            out ContentRangeHeaderValue parsedValue)
+            [NotNullWhen(true)]out ContentRangeHeaderValue? parsedValue)
         {
             parsedValue = null;
 

+ 2 - 4
src/Http/Headers/src/CookieHeaderParser.cs

@@ -13,7 +13,7 @@ namespace Microsoft.Net.Http.Headers
         {
         }
 
-        public override bool TryParseValue(StringSegment value, ref int index, out CookieHeaderValue parsedValue)
+        public override bool TryParseValue(StringSegment value, ref int index, out CookieHeaderValue? parsedValue)
         {
             parsedValue = null;
 
@@ -43,8 +43,7 @@ namespace Microsoft.Net.Http.Headers
                 return SupportsMultipleValues;
             }
 
-            CookieHeaderValue result = null;
-            if (!CookieHeaderValue.TryGetCookieLength(value, ref current, out result))
+            if (!CookieHeaderValue.TryGetCookieLength(value, ref current, out var result))
             {
                 return false;
             }
@@ -64,7 +63,6 @@ namespace Microsoft.Net.Http.Headers
 
         private static int GetNextNonEmptyOrWhitespaceIndex(StringSegment input, int startIndex, bool skipEmptyValues, out bool separatorFound)
         {
-            Contract.Requires(input != null);
             Contract.Requires(startIndex <= input.Length); // it's OK if index == value.Length.
 
             separatorFound = false;

+ 10 - 10
src/Http/Headers/src/CookieHeaderValue.cs

@@ -3,6 +3,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Diagnostics.Contracts;
 using System.Text;
 using Microsoft.Extensions.Primitives;
@@ -83,37 +84,37 @@ namespace Microsoft.Net.Http.Headers
         public static CookieHeaderValue Parse(StringSegment input)
         {
             var index = 0;
-            return SingleValueParser.ParseValue(input, ref index);
+            return SingleValueParser.ParseValue(input, ref index)!;
         }
 
-        public static bool TryParse(StringSegment input, out CookieHeaderValue parsedValue)
+        public static bool TryParse(StringSegment input, [NotNullWhen(true)] out CookieHeaderValue? parsedValue)
         {
             var index = 0;
-            return SingleValueParser.TryParseValue(input, ref index, out parsedValue);
+            return SingleValueParser.TryParseValue(input, ref index, out parsedValue!);
         }
 
-        public static IList<CookieHeaderValue> ParseList(IList<string> inputs)
+        public static IList<CookieHeaderValue> ParseList(IList<string>? inputs)
         {
             return MultipleValueParser.ParseValues(inputs);
         }
 
-        public static IList<CookieHeaderValue> ParseStrictList(IList<string> inputs)
+        public static IList<CookieHeaderValue> ParseStrictList(IList<string>? inputs)
         {
             return MultipleValueParser.ParseStrictValues(inputs);
         }
 
-        public static bool TryParseList(IList<string> inputs, out IList<CookieHeaderValue> parsedValues)
+        public static bool TryParseList(IList<string>? inputs, [NotNullWhen(true)] out IList<CookieHeaderValue>? parsedValues)
         {
             return MultipleValueParser.TryParseValues(inputs, out parsedValues);
         }
 
-        public static bool TryParseStrictList(IList<string> inputs, out IList<CookieHeaderValue> parsedValues)
+        public static bool TryParseStrictList(IList<string>? inputs, [NotNullWhen(true)] out IList<CookieHeaderValue>? parsedValues)
         {
             return MultipleValueParser.TryParseStrictValues(inputs, out parsedValues);
         }
 
         // name=value; name="value"
-        internal static bool TryGetCookieLength(StringSegment input, ref int offset, out CookieHeaderValue parsedValue)
+        internal static bool TryGetCookieLength(StringSegment input, ref int offset, [NotNullWhen(true)] out CookieHeaderValue? parsedValue)
         {
             Contract.Requires(offset >= 0);
 
@@ -158,7 +159,6 @@ namespace Microsoft.Net.Http.Headers
         //                     ; US-ASCII characters excluding CTLs, whitespace DQUOTE, comma, semicolon, and backslash
         internal static StringSegment GetCookieValue(StringSegment input, ref int offset)
         {
-            Contract.Requires(input != null);
             Contract.Requires(offset >= 0);
             Contract.Ensures((Contract.Result<int>() >= 0) && (Contract.Result<int>() <= (input.Length - offset)));
 
@@ -256,7 +256,7 @@ namespace Microsoft.Net.Http.Headers
             }
         }
 
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             var other = obj as CookieHeaderValue;
 

+ 14 - 13
src/Http/Headers/src/EntityTagHeaderValue.cs

@@ -3,6 +3,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Diagnostics.Contracts;
 using Microsoft.Extensions.Primitives;
 
@@ -13,15 +14,15 @@ namespace Microsoft.Net.Http.Headers
         // Note that the ETag header does not allow a * but we're not that strict: We allow both '*' and ETag values in a single value.
         // We can't guarantee that a single parsed value will be used directly in an ETag header.
         private static readonly HttpHeaderParser<EntityTagHeaderValue> SingleValueParser
-            = new GenericHeaderParser<EntityTagHeaderValue>(false, GetEntityTagLength);
+            = new GenericHeaderParser<EntityTagHeaderValue>(false, GetEntityTagLength!);
         // Note that if multiple ETag values are allowed (e.g. 'If-Match', 'If-None-Match'), according to the RFC
         // the value must either be '*' or a list of ETag values. It's not allowed to have both '*' and a list of
         // ETag values. We're not that strict: We allow both '*' and ETag values in a list. If the server sends such
         // an invalid list, we want to be able to represent it using the corresponding header property.
         private static readonly HttpHeaderParser<EntityTagHeaderValue> MultipleValueParser
-            = new GenericHeaderParser<EntityTagHeaderValue>(true, GetEntityTagLength);
+            = new GenericHeaderParser<EntityTagHeaderValue>(true, GetEntityTagLength!);
 
-        private static EntityTagHeaderValue AnyType;
+        private static EntityTagHeaderValue? AnyType;
 
         private StringSegment _tag;
         private bool _isWeak;
@@ -103,7 +104,7 @@ namespace Microsoft.Net.Http.Headers
         /// <c>true</c> if the strength and tag of the two values match,
         /// <c>false</c> if the other value is null, is not an <see cref="EntityTagHeaderValue"/>, or if there is a mismatch of strength or tag between the two values.
         /// </returns>
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             var other = obj as EntityTagHeaderValue;
 
@@ -131,7 +132,7 @@ namespace Microsoft.Net.Http.Headers
         /// <c>true</c> if the <see cref="EntityTagHeaderValue"/> match for the given comparison type,
         /// <c>false</c> if the other value is null or the comparison failed.
         /// </returns>
-        public bool Compare(EntityTagHeaderValue other, bool useStrongComparison)
+        public bool Compare(EntityTagHeaderValue? other, bool useStrongComparison)
         {
             if (other == null)
             {
@@ -151,36 +152,36 @@ namespace Microsoft.Net.Http.Headers
         public static EntityTagHeaderValue Parse(StringSegment input)
         {
             var index = 0;
-            return SingleValueParser.ParseValue(input, ref index);
+            return SingleValueParser.ParseValue(input, ref index)!;
         }
 
-        public static bool TryParse(StringSegment input, out EntityTagHeaderValue parsedValue)
+        public static bool TryParse(StringSegment input, [NotNullWhen(true)] out EntityTagHeaderValue parsedValue)
         {
             var index = 0;
-            return SingleValueParser.TryParseValue(input, ref index, out parsedValue);
+            return SingleValueParser.TryParseValue(input, ref index, out parsedValue!);
         }
 
-        public static IList<EntityTagHeaderValue> ParseList(IList<string> inputs)
+        public static IList<EntityTagHeaderValue> ParseList(IList<string>? inputs)
         {
             return MultipleValueParser.ParseValues(inputs);
         }
 
-        public static IList<EntityTagHeaderValue> ParseStrictList(IList<string> inputs)
+        public static IList<EntityTagHeaderValue> ParseStrictList(IList<string>? inputs)
         {
             return MultipleValueParser.ParseStrictValues(inputs);
         }
 
-        public static bool TryParseList(IList<string> inputs, out IList<EntityTagHeaderValue> parsedValues)
+        public static bool TryParseList(IList<string>? inputs, [NotNullWhen(true)] out IList<EntityTagHeaderValue>? parsedValues)
         {
             return MultipleValueParser.TryParseValues(inputs, out parsedValues);
         }
 
-        public static bool TryParseStrictList(IList<string> inputs, out IList<EntityTagHeaderValue> parsedValues)
+        public static bool TryParseStrictList(IList<string>? inputs, [NotNullWhen(true)] out IList<EntityTagHeaderValue>? parsedValues)
         {
             return MultipleValueParser.TryParseStrictValues(inputs, out parsedValues);
         }
 
-        internal static int GetEntityTagLength(StringSegment input, int startIndex, out EntityTagHeaderValue parsedValue)
+        internal static int GetEntityTagLength(StringSegment input, int startIndex, out EntityTagHeaderValue? parsedValue)
         {
             Contract.Requires(startIndex >= 0);
 

+ 3 - 2
src/Http/Headers/src/GenericHeaderParser.cs

@@ -2,13 +2,14 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System;
+using System.Diagnostics.CodeAnalysis;
 using Microsoft.Extensions.Primitives;
 
 namespace Microsoft.Net.Http.Headers
 {
     internal sealed class GenericHeaderParser<T> : BaseHeaderParser<T>
     {
-        internal delegate int GetParsedValueLengthDelegate(StringSegment value, int startIndex, out T parsedValue);
+        internal delegate int GetParsedValueLengthDelegate(StringSegment value, int startIndex, [MaybeNull] out T parsedValue);
 
         private GetParsedValueLengthDelegate _getParsedValueLength;
 
@@ -23,7 +24,7 @@ namespace Microsoft.Net.Http.Headers
             _getParsedValueLength = getParsedValueLength;
         }
 
-        protected override int GetParsedValueLength(StringSegment value, int startIndex, out T parsedValue)
+        protected override int GetParsedValueLength(StringSegment value, int startIndex, [MaybeNull] out T parsedValue)
         {
             return _getParsedValueLength(value, startIndex, out parsedValue);
         }

+ 3 - 8
src/Http/Headers/src/HeaderUtilities.cs

@@ -19,8 +19,6 @@ namespace Microsoft.Net.Http.Headers
 
         internal static void SetQuality(IList<NameValueHeaderValue> parameters, double? value)
         {
-            Contract.Requires(parameters != null);
-
             var qualityParameter = NameValueHeaderValue.Find(parameters, QualityName);
             if (value.HasValue)
             {
@@ -41,7 +39,7 @@ namespace Microsoft.Net.Http.Headers
                 }
                 else
                 {
-                    parameters.Add(new NameValueHeaderValue(QualityName, qualityString));
+                    parameters!.Add(new NameValueHeaderValue(QualityName, qualityString));
                 }
             }
             else
@@ -56,8 +54,6 @@ namespace Microsoft.Net.Http.Headers
 
         internal static double? GetQuality(IList<NameValueHeaderValue> parameters)
         {
-            Contract.Requires(parameters != null);
-
             var qualityParameter = NameValueHeaderValue.Find(parameters, QualityName);
             if (qualityParameter != null)
             {
@@ -85,12 +81,12 @@ namespace Microsoft.Net.Http.Headers
             }
         }
 
-        internal static bool AreEqualCollections<T>(ICollection<T> x, ICollection<T> y)
+        internal static bool AreEqualCollections<T>(ICollection<T>? x, ICollection<T>? y)
         {
             return AreEqualCollections(x, y, null);
         }
 
-        internal static bool AreEqualCollections<T>(ICollection<T> x, ICollection<T> y, IEqualityComparer<T> comparer)
+        internal static bool AreEqualCollections<T>(ICollection<T>? x, ICollection<T>? y, IEqualityComparer<T>? comparer)
         {
             if (x == null)
             {
@@ -157,7 +153,6 @@ namespace Microsoft.Net.Http.Headers
             bool skipEmptyValues,
             out bool separatorFound)
         {
-            Contract.Requires(input != null);
             Contract.Requires(startIndex <= input.Length); // it's OK if index == value.Length.
 
             separatorFound = false;

+ 13 - 13
src/Http/Headers/src/HttpHeaderParser.cs

@@ -3,6 +3,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Diagnostics.Contracts;
 using System.Globalization;
 using Microsoft.Extensions.Primitives;
@@ -11,7 +12,7 @@ namespace Microsoft.Net.Http.Headers
 {
     internal abstract class HttpHeaderParser<T>
     {
-        private bool _supportsMultipleValues;
+        private readonly bool _supportsMultipleValues;
 
         protected HttpHeaderParser(bool supportsMultipleValues)
         {
@@ -27,8 +28,9 @@ namespace Microsoft.Net.Http.Headers
         // pointing to the next non-whitespace character after a delimiter. E.g. if called with a start index of 0
         // for string "value , second_value", then after the call completes, 'index' must point to 's', i.e. the first
         // non-whitespace after the separator ','.
-        public abstract bool TryParseValue(StringSegment value, ref int index, out T parsedValue);
+        public abstract bool TryParseValue(StringSegment value, ref int index, [MaybeNull] out T parsedValue);
 
+        [return: MaybeNull]
         public T ParseValue(StringSegment value, ref int index)
         {
             // Index may be value.Length (e.g. both 0). This may be allowed for some headers (e.g. Accept but not
@@ -46,23 +48,23 @@ namespace Microsoft.Net.Http.Headers
             return result;
         }
 
-        public virtual bool TryParseValues(IList<string> values, out IList<T> parsedValues)
+        public virtual bool TryParseValues(IList<string>? values, [NotNullWhen(true)] out IList<T>? parsedValues)
         {
             return TryParseValues(values, strict: false, parsedValues: out parsedValues);
         }
 
-        public virtual bool TryParseStrictValues(IList<string> values, out IList<T> parsedValues)
+        public virtual bool TryParseStrictValues(IList<string>? values, [NotNullWhen(true)] out IList<T>? parsedValues)
         {
             return TryParseValues(values, strict: true, parsedValues: out parsedValues);
         }
 
-        protected virtual bool TryParseValues(IList<string> values, bool strict, out IList<T> parsedValues)
+        protected virtual bool TryParseValues(IList<string>? values, bool strict, [NotNullWhen(true)] out IList<T>? parsedValues)
         {
             Contract.Assert(_supportsMultipleValues);
             // If a parser returns an empty list, it means there was no value, but that's valid (e.g. "Accept: "). The caller
             // can ignore the value.
             parsedValues = null;
-            List<T> results = null;
+            List<T>? results = null;
             if (values == null)
             {
                 return false;
@@ -70,7 +72,7 @@ namespace Microsoft.Net.Http.Headers
             for (var i = 0; i < values.Count; i++)
             {
                 var value = values[i];
-                int index = 0;
+                var index = 0;
 
                 while (!string.IsNullOrEmpty(value) && index < value.Length)
                 {
@@ -106,17 +108,17 @@ namespace Microsoft.Net.Http.Headers
             return false;
         }
 
-        public virtual IList<T> ParseValues(IList<string> values)
+        public virtual IList<T> ParseValues(IList<string>? values)
         {
             return ParseValues(values, strict: false);
         }
 
-        public virtual IList<T> ParseStrictValues(IList<string> values)
+        public virtual IList<T> ParseStrictValues(IList<string>? values)
         {
             return ParseValues(values, strict: true);
         }
 
-        protected virtual IList<T> ParseValues(IList<string> values, bool strict)
+        protected virtual IList<T> ParseValues(IList<string>? values, bool strict)
         {
             Contract.Assert(_supportsMultipleValues);
             // If a parser returns an empty list, it means there was no value, but that's valid (e.g. "Accept: "). The caller
@@ -164,9 +166,7 @@ namespace Microsoft.Net.Http.Headers
         // for most headers (custom types, string, etc.).
         public virtual string ToString(object value)
         {
-            Contract.Requires(value != null);
-
-            return value.ToString();
+            return value.ToString()!;
         }
     }
 }

+ 0 - 4
src/Http/Headers/src/HttpRuleParser.cs

@@ -93,7 +93,6 @@ namespace Microsoft.Net.Http.Headers
         [Pure]
         internal static int GetTokenLength(StringSegment input, int startIndex)
         {
-            Contract.Requires(input != null);
             Contract.Ensures((Contract.Result<int>() >= 0) && (Contract.Result<int>() <= (input.Length - startIndex)));
 
             if (startIndex >= input.Length)
@@ -116,7 +115,6 @@ namespace Microsoft.Net.Http.Headers
 
         internal static int GetWhitespaceLength(StringSegment input, int startIndex)
         {
-            Contract.Requires(input != null);
             Contract.Ensures((Contract.Result<int>() >= 0) && (Contract.Result<int>() <= (input.Length - startIndex)));
 
             if (startIndex >= input.Length)
@@ -160,7 +158,6 @@ namespace Microsoft.Net.Http.Headers
 
         internal static int GetNumberLength(StringSegment input, int startIndex, bool allowDecimal)
         {
-            Contract.Requires(input != null);
             Contract.Requires((startIndex >= 0) && (startIndex < input.Length));
             Contract.Ensures((Contract.Result<int>() >= 0) && (Contract.Result<int>() <= (input.Length - startIndex)));
 
@@ -213,7 +210,6 @@ namespace Microsoft.Net.Http.Headers
         // CHAR = <any US-ASCII character (octets 0 - 127)>
         internal static HttpParseResult GetQuotedPairLength(StringSegment input, int startIndex, out int length)
         {
-            Contract.Requires(input != null);
             Contract.Requires((startIndex >= 0) && (startIndex < input.Length));
             Contract.Ensures((Contract.ValueAtReturn(out length) >= 0) &&
                 (Contract.ValueAtReturn(out length) <= (input.Length - startIndex)));

+ 17 - 16
src/Http/Headers/src/MediaTypeHeaderValue.cs

@@ -3,6 +3,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Diagnostics.Contracts;
 using System.Globalization;
 using System.Linq;
@@ -29,12 +30,12 @@ namespace Microsoft.Net.Http.Headers
         private static readonly char[] PeriodCharacterArray = new char[] { PeriodCharacter };
 
         private static readonly HttpHeaderParser<MediaTypeHeaderValue> SingleValueParser
-            = new GenericHeaderParser<MediaTypeHeaderValue>(false, GetMediaTypeLength);
+            = new GenericHeaderParser<MediaTypeHeaderValue>(false, GetMediaTypeLength!);
         private static readonly HttpHeaderParser<MediaTypeHeaderValue> MultipleValueParser
-            = new GenericHeaderParser<MediaTypeHeaderValue>(true, GetMediaTypeLength);
+            = new GenericHeaderParser<MediaTypeHeaderValue>(true, GetMediaTypeLength!);
 
         // Use a collection instead of a dictionary since we may have multiple parameters with the same name.
-        private ObjectCollection<NameValueHeaderValue> _parameters;
+        private ObjectCollection<NameValueHeaderValue>? _parameters;
         private StringSegment _mediaType;
         private bool _isReadOnly;
 
@@ -108,7 +109,7 @@ namespace Microsoft.Net.Http.Headers
         /// Gets or sets the value of the Encoding parameter. Setting the Encoding will set
         /// the <see cref="Charset"/> to <see cref="Encoding.WebName"/>.
         /// </summary>
-        public Encoding Encoding
+        public Encoding? Encoding
         {
             get
             {
@@ -205,7 +206,7 @@ namespace Microsoft.Net.Http.Headers
         /// </summary>
         public double? Quality
         {
-            get { return HeaderUtilities.GetQuality(_parameters); }
+            get { return HeaderUtilities.GetQuality(Parameters); }
             set
             {
                 HeaderUtilities.ThrowIfReadOnly(IsReadOnly);
@@ -444,7 +445,7 @@ namespace Microsoft.Net.Http.Headers
             return builder.ToString();
         }
 
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             var other = obj as MediaTypeHeaderValue;
 
@@ -471,7 +472,7 @@ namespace Microsoft.Net.Http.Headers
         public static MediaTypeHeaderValue Parse(StringSegment input)
         {
             var index = 0;
-            return SingleValueParser.ParseValue(input, ref index);
+            return SingleValueParser.ParseValue(input, ref index)!;
         }
 
         /// <summary>
@@ -480,10 +481,10 @@ namespace Microsoft.Net.Http.Headers
         /// <param name="input">The <see cref="StringSegment"/> with the media type. The media type constructed here must not have an y</param>
         /// <param name="parsedValue">The parsed <see cref="MediaTypeHeaderValue"/></param>
         /// <returns>True if the value was successfully parsed.</returns>
-        public static bool TryParse(StringSegment input, out MediaTypeHeaderValue parsedValue)
+        public static bool TryParse(StringSegment input, [NotNullWhen(true)] out MediaTypeHeaderValue? parsedValue)
         {
             var index = 0;
-            return SingleValueParser.TryParseValue(input, ref index, out parsedValue);
+            return SingleValueParser.TryParseValue(input, ref index, out parsedValue!);
         }
 
         /// <summary>
@@ -491,7 +492,7 @@ namespace Microsoft.Net.Http.Headers
         /// </summary>
         /// <param name="inputs">A list of media types</param>
         /// <returns>The parsed <see cref="MediaTypeHeaderValue"/>.</returns>
-        public static IList<MediaTypeHeaderValue> ParseList(IList<string> inputs)
+        public static IList<MediaTypeHeaderValue> ParseList(IList<string>? inputs)
         {
             return MultipleValueParser.ParseValues(inputs);
         }
@@ -502,7 +503,7 @@ namespace Microsoft.Net.Http.Headers
         /// </summary>
         /// <param name="inputs">A list of media types</param>
         /// <returns>The parsed <see cref="MediaTypeHeaderValue"/>.</returns>
-        public static IList<MediaTypeHeaderValue> ParseStrictList(IList<string> inputs)
+        public static IList<MediaTypeHeaderValue> ParseStrictList(IList<string>? inputs)
         {
             return MultipleValueParser.ParseStrictValues(inputs);
         }
@@ -513,7 +514,7 @@ namespace Microsoft.Net.Http.Headers
         /// <param name="inputs">A list of media types</param>
         /// <param name="parsedValues">The parsed <see cref="MediaTypeHeaderValue"/>.</param>
         /// <returns>True if the value was successfully parsed.</returns>
-        public static bool TryParseList(IList<string> inputs, out IList<MediaTypeHeaderValue> parsedValues)
+        public static bool TryParseList(IList<string>? inputs, [NotNullWhen(true)] out IList<MediaTypeHeaderValue>? parsedValues)
         {
             return MultipleValueParser.TryParseValues(inputs, out parsedValues);
         }
@@ -524,12 +525,12 @@ namespace Microsoft.Net.Http.Headers
         /// <param name="inputs">A list of media types</param>
         /// <param name="parsedValues">The parsed <see cref="MediaTypeHeaderValue"/>.</param>
         /// <returns>True if the value was successfully parsed.</returns>
-        public static bool TryParseStrictList(IList<string> inputs, out IList<MediaTypeHeaderValue> parsedValues)
+        public static bool TryParseStrictList(IList<string>? inputs, [NotNullWhen(true)] out IList<MediaTypeHeaderValue>? parsedValues)
         {
             return MultipleValueParser.TryParseStrictValues(inputs, out parsedValues);
         }
 
-        private static int GetMediaTypeLength(StringSegment input, int startIndex, out MediaTypeHeaderValue parsedValue)
+        private static int GetMediaTypeLength(StringSegment input, int startIndex, out MediaTypeHeaderValue? parsedValue)
         {
             Contract.Requires(startIndex >= 0);
 
@@ -550,7 +551,7 @@ namespace Microsoft.Net.Http.Headers
 
             var current = startIndex + mediaTypeLength;
             current = current + HttpRuleParser.GetWhitespaceLength(input, current);
-            MediaTypeHeaderValue mediaTypeHeader = null;
+            MediaTypeHeaderValue? mediaTypeHeader = null;
 
             // If we're not done and we have a parameter delimiter, then we have a list of parameters.
             if ((current < input.Length) && (input[current] == ';'))
@@ -575,7 +576,7 @@ namespace Microsoft.Net.Http.Headers
 
         private static int GetMediaTypeExpressionLength(StringSegment input, int startIndex, out StringSegment mediaType)
         {
-            Contract.Requires((input != null) && (input.Length > 0) && (startIndex < input.Length));
+            Contract.Requires((input.Length > 0) && (startIndex < input.Length));
 
             // This method just parses the "type/subtype" string, it does not parse parameters.
             mediaType = null;

+ 12 - 8
src/Http/Headers/src/MediaTypeHeaderValueComparer.cs

@@ -12,17 +12,11 @@ namespace Microsoft.Net.Http.Headers
     /// </summary>
     public class MediaTypeHeaderValueComparer : IComparer<MediaTypeHeaderValue>
     {
-        private static readonly MediaTypeHeaderValueComparer _mediaTypeComparer =
-                                                                    new MediaTypeHeaderValueComparer();
-
         private MediaTypeHeaderValueComparer()
         {
         }
 
-        public static MediaTypeHeaderValueComparer QualityComparer
-        {
-            get { return _mediaTypeComparer; }
-        }
+        public static MediaTypeHeaderValueComparer QualityComparer { get; } = new MediaTypeHeaderValueComparer();
 
         /// <inheritdoc />
         /// <remarks>
@@ -37,13 +31,23 @@ namespace Microsoft.Net.Http.Headers
         /// If we had a list of media types (comma separated): { text/*;q=0.8, text/*+json;q=0.8, */*;q=1, */*;q=0.8, text/plain;q=0.8 }
         /// Sorting them using Compare would return: { */*;q=0.8, text/*;q=0.8, text/*+json;q=0.8, text/plain;q=0.8, */*;q=1 }
         /// </example>
-        public int Compare(MediaTypeHeaderValue mediaType1, MediaTypeHeaderValue mediaType2)
+        public int Compare(MediaTypeHeaderValue? mediaType1, MediaTypeHeaderValue? mediaType2)
         {
             if (object.ReferenceEquals(mediaType1, mediaType2))
             {
                 return 0;
             }
 
+            if (mediaType1 is null)
+            {
+                return -1;
+            }
+
+            if (mediaType2 is null)
+            {
+                return 1;
+            }
+
             var returnValue = CompareBasedOnQualityFactor(mediaType1, mediaType2);
 
             if (returnValue == 0)

+ 1 - 0
src/Http/Headers/src/Microsoft.Net.Http.Headers.csproj

@@ -9,6 +9,7 @@
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <PackageTags>http</PackageTags>
     <IsPackable>false</IsPackable>
+    <Nullable>enable</Nullable>
   </PropertyGroup>
 
   <ItemGroup>

+ 19 - 23
src/Http/Headers/src/NameValueHeaderValue.cs

@@ -3,6 +3,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Diagnostics.Contracts;
 using System.Globalization;
 using System.Text;
@@ -16,9 +17,9 @@ namespace Microsoft.Net.Http.Headers
     public class NameValueHeaderValue
     {
         private static readonly HttpHeaderParser<NameValueHeaderValue> SingleValueParser
-            = new GenericHeaderParser<NameValueHeaderValue>(false, GetNameValueLength);
+            = new GenericHeaderParser<NameValueHeaderValue>(false, GetNameValueLength!);
         internal static readonly HttpHeaderParser<NameValueHeaderValue> MultipleValueParser
-            = new GenericHeaderParser<NameValueHeaderValue>(true, GetNameValueLength);
+            = new GenericHeaderParser<NameValueHeaderValue>(true, GetNameValueLength!);
 
         private StringSegment _name;
         private StringSegment _value;
@@ -109,7 +110,7 @@ namespace Microsoft.Net.Http.Headers
             return nameHashCode;
         }
 
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             var other = obj as NameValueHeaderValue;
 
@@ -168,31 +169,31 @@ namespace Microsoft.Net.Http.Headers
         public static NameValueHeaderValue Parse(StringSegment input)
         {
             var index = 0;
-            return SingleValueParser.ParseValue(input, ref index);
+            return SingleValueParser.ParseValue(input, ref index)!;
         }
 
-        public static bool TryParse(StringSegment input, out NameValueHeaderValue parsedValue)
+        public static bool TryParse(StringSegment input, [NotNullWhen(true)] out NameValueHeaderValue? parsedValue)
         {
             var index = 0;
-            return SingleValueParser.TryParseValue(input, ref index, out parsedValue);
+            return SingleValueParser.TryParseValue(input, ref index, out parsedValue!);
         }
 
-        public static IList<NameValueHeaderValue> ParseList(IList<string> input)
+        public static IList<NameValueHeaderValue> ParseList(IList<string>? input)
         {
             return MultipleValueParser.ParseValues(input);
         }
 
-        public static IList<NameValueHeaderValue> ParseStrictList(IList<string> input)
+        public static IList<NameValueHeaderValue> ParseStrictList(IList<string>? input)
         {
             return MultipleValueParser.ParseStrictValues(input);
         }
 
-        public static bool TryParseList(IList<string> input, out IList<NameValueHeaderValue> parsedValues)
+        public static bool TryParseList(IList<string>? input, [NotNullWhen(true)] out IList<NameValueHeaderValue>? parsedValues)
         {
             return MultipleValueParser.TryParseValues(input, out parsedValues);
         }
 
-        public static bool TryParseStrictList(IList<string> input, out IList<NameValueHeaderValue> parsedValues)
+        public static bool TryParseStrictList(IList<string>? input, [NotNullWhen(true)] out IList<NameValueHeaderValue>? parsedValues)
         {
             return MultipleValueParser.TryParseStrictValues(input, out parsedValues);
         }
@@ -207,7 +208,7 @@ namespace Microsoft.Net.Http.Headers
         }
 
         internal static void ToString(
-            IList<NameValueHeaderValue> values,
+            IList<NameValueHeaderValue>? values,
             char separator,
             bool leadingSeparator,
             StringBuilder destination)
@@ -235,7 +236,7 @@ namespace Microsoft.Net.Http.Headers
             }
         }
 
-        internal static string ToString(IList<NameValueHeaderValue> values, char separator, bool leadingSeparator)
+        internal static string? ToString(IList<NameValueHeaderValue>? values, char separator, bool leadingSeparator)
         {
             if ((values == null) || (values.Count == 0))
             {
@@ -249,7 +250,7 @@ namespace Microsoft.Net.Http.Headers
             return sb.ToString();
         }
 
-        internal static int GetHashCode(IList<NameValueHeaderValue> values)
+        internal static int GetHashCode(IList<NameValueHeaderValue>? values)
         {
             if ((values == null) || (values.Count == 0))
             {
@@ -264,9 +265,8 @@ namespace Microsoft.Net.Http.Headers
             return result;
         }
 
-        private static int GetNameValueLength(StringSegment input, int startIndex, out NameValueHeaderValue parsedValue)
+        private static int GetNameValueLength(StringSegment input, int startIndex, out NameValueHeaderValue? parsedValue)
         {
-            Contract.Requires(input != null);
             Contract.Requires(startIndex >= 0);
 
             parsedValue = null;
@@ -323,7 +323,6 @@ namespace Microsoft.Net.Http.Headers
             char delimiter,
             IList<NameValueHeaderValue> nameValueCollection)
         {
-            Contract.Requires(nameValueCollection != null);
             Contract.Requires(startIndex >= 0);
 
             if ((StringSegment.IsNullOrEmpty(input)) || (startIndex >= input.Length))
@@ -334,8 +333,7 @@ namespace Microsoft.Net.Http.Headers
             var current = startIndex + HttpRuleParser.GetWhitespaceLength(input, startIndex);
             while (true)
             {
-                NameValueHeaderValue parameter = null;
-                var nameValueLength = GetNameValueLength(input, current, out parameter);
+                var nameValueLength = GetNameValueLength(input, current, out var parameter);
 
                 if (nameValueLength == 0)
                 {
@@ -343,7 +341,7 @@ namespace Microsoft.Net.Http.Headers
                     return current - startIndex;
                 }
 
-                nameValueCollection.Add(parameter);
+                nameValueCollection!.Add(parameter!);
                 current = current + nameValueLength;
                 current = current + HttpRuleParser.GetWhitespaceLength(input, current);
 
@@ -359,9 +357,9 @@ namespace Microsoft.Net.Http.Headers
             }
         }
 
-        public static NameValueHeaderValue Find(IList<NameValueHeaderValue> values, StringSegment name)
+        public static NameValueHeaderValue? Find(IList<NameValueHeaderValue>? values, StringSegment name)
         {
-            Contract.Requires((name != null) && (name.Length > 0));
+            Contract.Requires(name.Length > 0);
 
             if ((values == null) || (values.Count == 0))
             {
@@ -381,8 +379,6 @@ namespace Microsoft.Net.Http.Headers
 
         internal static int GetValueLength(StringSegment input, int startIndex)
         {
-            Contract.Requires(input != null);
-
             if (startIndex >= input.Length)
             {
                 return 0;

+ 2 - 2
src/Http/Headers/src/ObjectCollection.cs

@@ -21,7 +21,7 @@ namespace Microsoft.Net.Http.Headers
 
         // We need to create a 'read-only' inner list for Collection<T> to do the right
         // thing.
-        private static IList<T> CreateInnerList(bool isReadOnly, IEnumerable <T> other = null)
+        private static IList<T> CreateInnerList(bool isReadOnly, IEnumerable<T>? other = null)
         {
             var list = other == null ? new List<T>() : new List<T>(other);
             if (isReadOnly)
@@ -78,4 +78,4 @@ namespace Microsoft.Net.Http.Headers
             }
         }
     }
-}
+}

+ 13 - 12
src/Http/Headers/src/RangeConditionHeaderValue.cs

@@ -2,6 +2,7 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System;
+using System.Diagnostics.CodeAnalysis;
 using System.Diagnostics.Contracts;
 using Microsoft.Extensions.Primitives;
 
@@ -10,10 +11,10 @@ namespace Microsoft.Net.Http.Headers
     public class RangeConditionHeaderValue
     {
         private static readonly HttpHeaderParser<RangeConditionHeaderValue> Parser
-            = new GenericHeaderParser<RangeConditionHeaderValue>(false, GetRangeConditionLength);
+            = new GenericHeaderParser<RangeConditionHeaderValue>(false, GetRangeConditionLength!);
 
         private DateTimeOffset? _lastModified;
-        private EntityTagHeaderValue _entityTag;
+        private EntityTagHeaderValue? _entityTag;
 
         private RangeConditionHeaderValue()
         {
@@ -25,7 +26,7 @@ namespace Microsoft.Net.Http.Headers
             _lastModified = lastModified;
         }
 
-        public RangeConditionHeaderValue(EntityTagHeaderValue entityTag)
+        public RangeConditionHeaderValue(EntityTagHeaderValue? entityTag)
         {
             if (entityTag == null)
             {
@@ -35,7 +36,7 @@ namespace Microsoft.Net.Http.Headers
             _entityTag = entityTag;
         }
 
-        public RangeConditionHeaderValue(string entityTag)
+        public RangeConditionHeaderValue(string? entityTag)
             : this(new EntityTagHeaderValue(entityTag))
         {
         }
@@ -45,7 +46,7 @@ namespace Microsoft.Net.Http.Headers
             get { return _lastModified; }
         }
 
-        public EntityTagHeaderValue EntityTag
+        public EntityTagHeaderValue? EntityTag
         {
             get { return _entityTag; }
         }
@@ -59,7 +60,7 @@ namespace Microsoft.Net.Http.Headers
             return _entityTag.ToString();
         }
 
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             var other = obj as RangeConditionHeaderValue;
 
@@ -89,16 +90,16 @@ namespace Microsoft.Net.Http.Headers
         public static RangeConditionHeaderValue Parse(StringSegment input)
         {
             var index = 0;
-            return Parser.ParseValue(input, ref index);
+            return Parser.ParseValue(input, ref index)!;
         }
 
-        public static bool TryParse(StringSegment input, out RangeConditionHeaderValue parsedValue)
+        public static bool TryParse(StringSegment input, [NotNullWhen(true)] out RangeConditionHeaderValue? parsedValue)
         {
             var index = 0;
-            return Parser.TryParseValue(input, ref index, out parsedValue);
+            return Parser.TryParseValue(input, ref index, out parsedValue!);
         }
 
-        private static int GetRangeConditionLength(StringSegment input, int startIndex, out RangeConditionHeaderValue parsedValue)
+        private static int GetRangeConditionLength(StringSegment input, int startIndex, out RangeConditionHeaderValue? parsedValue)
         {
             Contract.Requires(startIndex >= 0);
 
@@ -114,7 +115,7 @@ namespace Microsoft.Net.Http.Headers
 
             // Caller must remove leading whitespaces.
             DateTimeOffset date = DateTimeOffset.MinValue;
-            EntityTagHeaderValue entityTag = null;
+            EntityTagHeaderValue? entityTag = null;
 
             // Entity tags are quoted strings optionally preceded by "W/". By looking at the first two character we
             // can determine whether the string is en entity tag or a date.
@@ -164,4 +165,4 @@ namespace Microsoft.Net.Http.Headers
             return current - startIndex;
         }
     }
-}
+}

+ 8 - 7
src/Http/Headers/src/RangeHeaderValue.cs

@@ -3,6 +3,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Diagnostics.Contracts;
 using System.Text;
 using Microsoft.Extensions.Primitives;
@@ -12,10 +13,10 @@ namespace Microsoft.Net.Http.Headers
     public class RangeHeaderValue
     {
         private static readonly HttpHeaderParser<RangeHeaderValue> Parser
-            = new GenericHeaderParser<RangeHeaderValue>(false, GetRangeLength);
+            = new GenericHeaderParser<RangeHeaderValue>(false, GetRangeLength!);
 
         private StringSegment _unit;
-        private ICollection<RangeItemHeaderValue> _ranges;
+        private ICollection<RangeItemHeaderValue>? _ranges;
 
         public RangeHeaderValue()
         {
@@ -77,7 +78,7 @@ namespace Microsoft.Net.Http.Headers
             return sb.ToString();
         }
 
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             var other = obj as RangeHeaderValue;
 
@@ -105,16 +106,16 @@ namespace Microsoft.Net.Http.Headers
         public static RangeHeaderValue Parse(StringSegment input)
         {
             var index = 0;
-            return Parser.ParseValue(input, ref index);
+            return Parser.ParseValue(input, ref index)!;
         }
 
-        public static bool TryParse(StringSegment input, out RangeHeaderValue parsedValue)
+        public static bool TryParse(StringSegment input, [NotNullWhen(true)] out RangeHeaderValue parsedValue)
         {
             var index = 0;
-            return Parser.TryParseValue(input, ref index, out parsedValue);
+            return Parser.TryParseValue(input, ref index, out parsedValue!);
         }
 
-        private static int GetRangeLength(StringSegment input, int startIndex, out RangeHeaderValue parsedValue)
+        private static int GetRangeLength(StringSegment input, int startIndex, out RangeHeaderValue? parsedValue)
         {
             Contract.Requires(startIndex >= 0);
 

+ 4 - 5
src/Http/Headers/src/RangeItemHeaderValue.cs

@@ -61,7 +61,7 @@ namespace Microsoft.Net.Http.Headers
                 _to.GetValueOrDefault().ToString(NumberFormatInfo.InvariantInfo);
         }
 
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             if (obj is RangeItemHeaderValue other)
             {
@@ -91,7 +91,6 @@ namespace Microsoft.Net.Http.Headers
             int startIndex,
             ICollection<RangeItemHeaderValue> rangeCollection)
         {
-            Contract.Requires(rangeCollection != null);
             Contract.Requires(startIndex >= 0);
             Contract.Ensures((Contract.Result<int>() == 0) || (rangeCollection.Count > 0),
                 "If we can parse the string, then we expect to have at least one range item.");
@@ -111,7 +110,7 @@ namespace Microsoft.Net.Http.Headers
                 return 0;
             }
 
-            RangeItemHeaderValue range = null;
+            RangeItemHeaderValue? range = null;
             while (true)
             {
                 var rangeLength = GetRangeItemLength(input, current, out range);
@@ -121,7 +120,7 @@ namespace Microsoft.Net.Http.Headers
                     return 0;
                 }
 
-                rangeCollection.Add(range);
+                rangeCollection!.Add(range!);
 
                 current = current + rangeLength;
                 current = HeaderUtilities.GetNextNonEmptyOrWhitespaceIndex(input, current, true, out separatorFound);
@@ -140,7 +139,7 @@ namespace Microsoft.Net.Http.Headers
             }
         }
 
-        internal static int GetRangeItemLength(StringSegment input, int startIndex, out RangeItemHeaderValue parsedValue)
+        internal static int GetRangeItemLength(StringSegment input, int startIndex, out RangeItemHeaderValue? parsedValue)
         {
             Contract.Requires(startIndex >= 0);
 

+ 14 - 13
src/Http/Headers/src/SetCookieHeaderValue.cs

@@ -4,6 +4,7 @@
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.Diagnostics.Contracts;
 using System.Text;
 using Microsoft.Extensions.Primitives;
@@ -31,9 +32,9 @@ namespace Microsoft.Net.Http.Headers
         private const string ExpiresDateFormat = "r";
 
         private static readonly HttpHeaderParser<SetCookieHeaderValue> SingleValueParser
-            = new GenericHeaderParser<SetCookieHeaderValue>(false, GetSetCookieLength);
+            = new GenericHeaderParser<SetCookieHeaderValue>(false, GetSetCookieLength!);
         private static readonly HttpHeaderParser<SetCookieHeaderValue> MultipleValueParser
-            = new GenericHeaderParser<SetCookieHeaderValue>(true, GetSetCookieLength);
+            = new GenericHeaderParser<SetCookieHeaderValue>(true, GetSetCookieLength!);
 
         private StringSegment _name;
         private StringSegment _value;
@@ -103,8 +104,8 @@ namespace Microsoft.Net.Http.Headers
         {
             var length = _name.Length + EqualsToken.Length + _value.Length;
 
-            string maxAge = null;
-            string sameSite = null;
+            string? maxAge = null;
+            string? sameSite = null;
 
             if (Expires.HasValue)
             {
@@ -296,37 +297,37 @@ namespace Microsoft.Net.Http.Headers
         public static SetCookieHeaderValue Parse(StringSegment input)
         {
             var index = 0;
-            return SingleValueParser.ParseValue(input, ref index);
+            return SingleValueParser.ParseValue(input, ref index)!;
         }
 
-        public static bool TryParse(StringSegment input, out SetCookieHeaderValue parsedValue)
+        public static bool TryParse(StringSegment input, [NotNullWhen(true)] out SetCookieHeaderValue? parsedValue)
         {
             var index = 0;
-            return SingleValueParser.TryParseValue(input, ref index, out parsedValue);
+            return SingleValueParser.TryParseValue(input, ref index, out parsedValue!);
         }
 
-        public static IList<SetCookieHeaderValue> ParseList(IList<string> inputs)
+        public static IList<SetCookieHeaderValue> ParseList(IList<string>? inputs)
         {
             return MultipleValueParser.ParseValues(inputs);
         }
 
-        public static IList<SetCookieHeaderValue> ParseStrictList(IList<string> inputs)
+        public static IList<SetCookieHeaderValue> ParseStrictList(IList<string>? inputs)
         {
             return MultipleValueParser.ParseStrictValues(inputs);
         }
 
-        public static bool TryParseList(IList<string> inputs, out IList<SetCookieHeaderValue> parsedValues)
+        public static bool TryParseList(IList<string>? inputs, [NotNullWhen(true)] out IList<SetCookieHeaderValue>? parsedValues)
         {
             return MultipleValueParser.TryParseValues(inputs, out parsedValues);
         }
 
-        public static bool TryParseStrictList(IList<string> inputs, out IList<SetCookieHeaderValue> parsedValues)
+        public static bool TryParseStrictList(IList<string>? inputs, [NotNullWhen(true)] out IList<SetCookieHeaderValue>? parsedValues)
         {
             return MultipleValueParser.TryParseStrictValues(inputs, out parsedValues);
         }
 
         // name=value; expires=Sun, 06 Nov 1994 08:49:37 GMT; max-age=86400; domain=domain1; path=path1; secure; samesite={Strict|Lax|None}; httponly
-        private static int GetSetCookieLength(StringSegment input, int startIndex, out SetCookieHeaderValue parsedValue)
+        private static int GetSetCookieLength(StringSegment input, int startIndex, out SetCookieHeaderValue? parsedValue)
         {
             Contract.Requires(startIndex >= 0);
             var offset = startIndex;
@@ -537,7 +538,7 @@ namespace Microsoft.Net.Http.Headers
             return result;
         }
 
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             var other = obj as SetCookieHeaderValue;
 

+ 12 - 11
src/Http/Headers/src/StringWithQualityHeaderValue.cs

@@ -3,6 +3,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Diagnostics.Contracts;
 using System.Globalization;
 using Microsoft.Extensions.Primitives;
@@ -12,9 +13,9 @@ namespace Microsoft.Net.Http.Headers
     public class StringWithQualityHeaderValue
     {
         private static readonly HttpHeaderParser<StringWithQualityHeaderValue> SingleValueParser
-            = new GenericHeaderParser<StringWithQualityHeaderValue>(false, GetStringWithQualityLength);
+            = new GenericHeaderParser<StringWithQualityHeaderValue>(false, GetStringWithQualityLength!);
         private static readonly HttpHeaderParser<StringWithQualityHeaderValue> MultipleValueParser
-            = new GenericHeaderParser<StringWithQualityHeaderValue>(true, GetStringWithQualityLength);
+            = new GenericHeaderParser<StringWithQualityHeaderValue>(true, GetStringWithQualityLength!);
 
         private StringSegment _value;
         private double? _quality;
@@ -64,7 +65,7 @@ namespace Microsoft.Net.Http.Headers
             return _value.ToString();
         }
 
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             var other = obj as StringWithQualityHeaderValue;
 
@@ -106,36 +107,36 @@ namespace Microsoft.Net.Http.Headers
         public static StringWithQualityHeaderValue Parse(StringSegment input)
         {
             var index = 0;
-            return SingleValueParser.ParseValue(input, ref index);
+            return SingleValueParser.ParseValue(input, ref index)!;
         }
 
-        public static bool TryParse(StringSegment input, out StringWithQualityHeaderValue parsedValue)
+        public static bool TryParse(StringSegment input, [NotNullWhen(true)] out StringWithQualityHeaderValue parsedValue)
         {
             var index = 0;
-            return SingleValueParser.TryParseValue(input, ref index, out parsedValue);
+            return SingleValueParser.TryParseValue(input, ref index, out parsedValue!);
         }
 
-        public static IList<StringWithQualityHeaderValue> ParseList(IList<string> input)
+        public static IList<StringWithQualityHeaderValue> ParseList(IList<string>? input)
         {
             return MultipleValueParser.ParseValues(input);
         }
 
-        public static IList<StringWithQualityHeaderValue> ParseStrictList(IList<string> input)
+        public static IList<StringWithQualityHeaderValue> ParseStrictList(IList<string>? input)
         {
             return MultipleValueParser.ParseStrictValues(input);
         }
 
-        public static bool TryParseList(IList<string> input, out IList<StringWithQualityHeaderValue> parsedValues)
+        public static bool TryParseList(IList<string>? input, [NotNullWhen(true)] out IList<StringWithQualityHeaderValue>? parsedValues)
         {
             return MultipleValueParser.TryParseValues(input, out parsedValues);
         }
 
-        public static bool TryParseStrictList(IList<string> input, out IList<StringWithQualityHeaderValue> parsedValues)
+        public static bool TryParseStrictList(IList<string>? input, [NotNullWhen(true)] out IList<StringWithQualityHeaderValue>? parsedValues)
         {
             return MultipleValueParser.TryParseStrictValues(input, out parsedValues);
         }
 
-        private static int GetStringWithQualityLength(StringSegment input, int startIndex, out StringWithQualityHeaderValue parsedValue)
+        private static int GetStringWithQualityLength(StringSegment input, int startIndex, out StringWithQualityHeaderValue? parsedValue)
         {
             Contract.Requires(startIndex >= 0);
 

+ 3 - 9
src/Http/Headers/src/StringWithQualityHeaderValueComparer.cs

@@ -16,17 +16,11 @@ namespace Microsoft.Net.Http.Headers
     /// </summary>
     public class StringWithQualityHeaderValueComparer : IComparer<StringWithQualityHeaderValue>
     {
-        private static readonly StringWithQualityHeaderValueComparer _qualityComparer =
-            new StringWithQualityHeaderValueComparer();
-
         private StringWithQualityHeaderValueComparer()
         {
         }
 
-        public static StringWithQualityHeaderValueComparer QualityComparer
-        {
-            get { return _qualityComparer; }
-        }
+        public static StringWithQualityHeaderValueComparer QualityComparer { get; } = new StringWithQualityHeaderValueComparer();
 
         /// <summary>
         /// Compares two <see cref="StringWithQualityHeaderValue"/> based on their quality value
@@ -40,8 +34,8 @@ namespace Microsoft.Net.Http.Headers
         /// <param name="stringWithQuality2">The second value to compare</param>
         /// <returns>The result of the comparison.</returns>
         public int Compare(
-            StringWithQualityHeaderValue stringWithQuality1,
-            StringWithQualityHeaderValue stringWithQuality2)
+            StringWithQualityHeaderValue? stringWithQuality1,
+            StringWithQualityHeaderValue? stringWithQuality2)
         {
             if (stringWithQuality1 == null)
             {

+ 9 - 11
src/Http/Headers/test/CacheControlHeaderValueTest.cs

@@ -62,7 +62,7 @@ namespace Microsoft.Net.Http.Headers
 
             // NameValueHeaderValue collection property
             Assert.NotNull(cacheControl.Extensions);
-            Assert.Throws<ArgumentNullException>(() => cacheControl.Extensions.Add(null));
+            Assert.Throws<ArgumentNullException>(() => cacheControl.Extensions.Add(null!));
             cacheControl.Extensions.Add(new NameValueHeaderValue("name", "value"));
             Assert.Equal(1, cacheControl.Extensions.Count);
             Assert.Equal(new NameValueHeaderValue("name", "value"), cacheControl.Extensions.First());
@@ -351,9 +351,9 @@ namespace Microsoft.Net.Http.Headers
             cacheControl2.NoCacheHeaders.Add("token1");
             cacheControl2.NoCacheHeaders.Add("token2");
 
-            CompareValues(cacheControl1, cacheControl2, false);
+            CompareValues(cacheControl1!, cacheControl2, false);
 
-            cacheControl1.NoCacheHeaders.Add("token1");
+            cacheControl1!.NoCacheHeaders.Add("token1");
             CompareValues(cacheControl1, cacheControl2, true);
 
             // Since NoCache and Private generate different hash codes, even if NoCacheHeaders and PrivateHeaders
@@ -569,28 +569,26 @@ namespace Microsoft.Net.Http.Headers
             Assert.Equal(areEqual, y.Equals(x));
         }
 
-        private void CheckValidParse(string input, CacheControlHeaderValue expectedResult)
+        private void CheckValidParse(string? input, CacheControlHeaderValue expectedResult)
         {
             var result = CacheControlHeaderValue.Parse(input);
             Assert.Equal(expectedResult, result);
         }
 
-        private void CheckInvalidParse(string input)
+        private void CheckInvalidParse(string? input)
         {
             Assert.Throws<FormatException>(() => CacheControlHeaderValue.Parse(input));
         }
 
-        private void CheckValidTryParse(string input, CacheControlHeaderValue expectedResult)
+        private void CheckValidTryParse(string? input, CacheControlHeaderValue expectedResult)
         {
-            CacheControlHeaderValue result = null;
-            Assert.True(CacheControlHeaderValue.TryParse(input, out result));
+            Assert.True(CacheControlHeaderValue.TryParse(input, out var result));
             Assert.Equal(expectedResult, result);
         }
 
-        private void CheckInvalidTryParse(string input)
+        private void CheckInvalidTryParse(string? input)
         {
-            CacheControlHeaderValue result = null;
-            Assert.False(CacheControlHeaderValue.TryParse(input, out result));
+            Assert.False(CacheControlHeaderValue.TryParse(input, out var result));
             Assert.Null(result);
         }
 

+ 8 - 10
src/Http/Headers/test/ContentDispositionHeaderValueTest.cs

@@ -58,7 +58,7 @@ namespace Microsoft.Net.Http.Headers
         public void Parameters_AddNull_Throw()
         {
             var contentDisposition = new ContentDispositionHeaderValue("inline");
-            Assert.Throws<ArgumentNullException>(() => contentDisposition.Parameters.Add(null));
+            Assert.Throws<ArgumentNullException>(() => contentDisposition.Parameters.Add(null!));
         }
 
         [Fact]
@@ -414,7 +414,7 @@ namespace Microsoft.Net.Http.Headers
             Assert.False(contentDisposition1.Equals(contentDisposition2), "No params vs. name.");
             Assert.False(contentDisposition2.Equals(contentDisposition1), "name vs. no params.");
             Assert.False(contentDisposition1.Equals(null), "No params vs. <null>.");
-            Assert.False(contentDisposition1.Equals(contentDisposition3), "No params vs. custom param.");
+            Assert.False(contentDisposition1!.Equals(contentDisposition3), "No params vs. custom param.");
             Assert.False(contentDisposition2.Equals(contentDisposition3), "name vs. custom param.");
             Assert.True(contentDisposition1.Equals(contentDisposition4), "Different casing.");
             Assert.True(contentDisposition2.Equals(contentDisposition5), "Different casing in name.");
@@ -615,28 +615,26 @@ namespace Microsoft.Net.Http.Headers
             public bool Valid { get; }
         }
 
-        private void CheckValidParse(string input, ContentDispositionHeaderValue expectedResult)
+        private void CheckValidParse(string? input, ContentDispositionHeaderValue expectedResult)
         {
             var result = ContentDispositionHeaderValue.Parse(input);
             Assert.Equal(expectedResult, result);
         }
 
-        private void CheckInvalidParse(string input)
+        private void CheckInvalidParse(string? input)
         {
             Assert.Throws<FormatException>(() => ContentDispositionHeaderValue.Parse(input));
         }
 
-        private void CheckValidTryParse(string input, ContentDispositionHeaderValue expectedResult)
+        private void CheckValidTryParse(string? input, ContentDispositionHeaderValue expectedResult)
         {
-            ContentDispositionHeaderValue result = null;
-            Assert.True(ContentDispositionHeaderValue.TryParse(input, out result), input);
+            Assert.True(ContentDispositionHeaderValue.TryParse(input, out var result), input);
             Assert.Equal(expectedResult, result);
         }
 
-        private void CheckInvalidTryParse(string input)
+        private void CheckInvalidTryParse(string? input)
         {
-            ContentDispositionHeaderValue result = null;
-            Assert.False(ContentDispositionHeaderValue.TryParse(input, out result), input);
+            Assert.False(ContentDispositionHeaderValue.TryParse(input, out var result), input);
             Assert.Null(result);
         }
 

+ 8 - 11
src/Http/Headers/test/ContentRangeHeaderValueTest.cs

@@ -132,7 +132,7 @@ namespace Microsoft.Net.Http.Headers
             var range8 = new ContentRangeHeaderValue(1, 2, 6);
 
             Assert.False(range1.Equals(null), "bytes 1-2/5 vs. <null>");
-            Assert.False(range1.Equals(range2), "bytes 1-2/5 vs. bytes 1-2/*");
+            Assert.False(range1!.Equals(range2), "bytes 1-2/5 vs. bytes 1-2/*");
             Assert.False(range1.Equals(range3), "bytes 1-2/5 vs. bytes */5");
             Assert.False(range2.Equals(range3), "bytes 1-2/* vs. bytes */5");
             Assert.True(range1.Equals(range4), "bytes 1-2/5 vs. BYTES 1-2/5");
@@ -193,7 +193,7 @@ namespace Microsoft.Net.Http.Headers
         [InlineData("bytes 1-9999999999999999999/3")]
         [InlineData("bytes 9999999999999999999-3/3")]
         [InlineData("bytes 1-2/9999999999999999999")]
-        public void Parse_SetOfInvalidValueStrings_Throws(string input)
+        public void Parse_SetOfInvalidValueStrings_Throws(string? input)
         {
             Assert.Throws<FormatException>(() => ContentRangeHeaderValue.Parse(input));
         }
@@ -212,8 +212,7 @@ namespace Microsoft.Net.Http.Headers
 
             // Note that we don't have a public constructor for value 'bytes */*' since the RFC doesn't mention a
             // scenario for it. However, if a server returns this value, we're flexible and accept it.
-            ContentRangeHeaderValue result = null;
-            Assert.True(ContentRangeHeaderValue.TryParse("bytes */*", out result));
+            Assert.True(ContentRangeHeaderValue.TryParse("bytes */*", out var result));
             Assert.Equal("bytes", result.Unit);
             Assert.Null(result.From);
             Assert.Null(result.To);
@@ -249,23 +248,21 @@ namespace Microsoft.Net.Http.Headers
         [InlineData("bytes 1-9999999999999999999/3")]
         [InlineData("bytes 9999999999999999999-3/3")]
         [InlineData("bytes 1-2/9999999999999999999")]
-        public void TryParse_SetOfInvalidValueStrings_ReturnsFalse(string input)
+        public void TryParse_SetOfInvalidValueStrings_ReturnsFalse(string? input)
         {
-            ContentRangeHeaderValue result = null;
-            Assert.False(ContentRangeHeaderValue.TryParse(input, out result));
+            Assert.False(ContentRangeHeaderValue.TryParse(input, out var result));
             Assert.Null(result);
         }
 
-        private void CheckValidParse(string input, ContentRangeHeaderValue expectedResult)
+        private void CheckValidParse(string? input, ContentRangeHeaderValue expectedResult)
         {
             var result = ContentRangeHeaderValue.Parse(input);
             Assert.Equal(expectedResult, result);
         }
 
-        private void CheckValidTryParse(string input, ContentRangeHeaderValue expectedResult)
+        private void CheckValidTryParse(string? input, ContentRangeHeaderValue expectedResult)
         {
-            ContentRangeHeaderValue result = null;
-            Assert.True(ContentRangeHeaderValue.TryParse(input, out result));
+            Assert.True(ContentRangeHeaderValue.TryParse(input, out var result));
             Assert.Equal(expectedResult, result);
         }
     }

+ 6 - 6
src/Http/Headers/test/CookieHeaderValueTest.cs

@@ -80,11 +80,11 @@ namespace Microsoft.Net.Http.Headers
             }
         }
 
-        public static TheoryData<IList<CookieHeaderValue>, string[]> ListOfCookieHeaderDataSet
+        public static TheoryData<IList<CookieHeaderValue>, string?[]> ListOfCookieHeaderDataSet
         {
             get
             {
-                var dataset = new TheoryData<IList<CookieHeaderValue>, string[]>();
+                var dataset = new TheoryData<IList<CookieHeaderValue>, string?[]>();
                 var header1 = new CookieHeaderValue("name1", "n1=v1&n2=v2&n3=v3");
                 var string1 = "name1=n1=v1&n2=v2&n3=v3";
 
@@ -99,7 +99,7 @@ namespace Microsoft.Net.Http.Headers
 
                 dataset.Add(new[] { header1 }.ToList(), new[] { string1 });
                 dataset.Add(new[] { header1, header1 }.ToList(), new[] { string1, string1 });
-                dataset.Add(new[] { header1, header1 }.ToList(), new[] { string1, null, "", " ", ";", " , ", string1 });
+                dataset.Add(new[] { header1, header1 }.ToList(), new [] { string1, null, "", " ", ";", " , ", string1 });
                 dataset.Add(new[] { header2 }.ToList(), new[] { string2 });
                 dataset.Add(new[] { header1, header2 }.ToList(), new[] { string1, string2 });
                 dataset.Add(new[] { header1, header2 }.ToList(), new[] { string1 + ", " + string2 });
@@ -112,11 +112,11 @@ namespace Microsoft.Net.Http.Headers
             }
         }
 
-        public static TheoryData<IList<CookieHeaderValue>, string[]> ListWithInvalidCookieHeaderDataSet
+        public static TheoryData<IList<CookieHeaderValue>?, string?[]> ListWithInvalidCookieHeaderDataSet
         {
             get
             {
-                var dataset = new TheoryData<IList<CookieHeaderValue>, string[]>();
+                var dataset = new TheoryData<IList<CookieHeaderValue>?, string?[]>();
                 var header1 = new CookieHeaderValue("name1", "n1=v1&n2=v2&n3=v3");
                 var validString1 = "name1=n1=v1&n2=v2&n3=v3";
 
@@ -226,7 +226,7 @@ namespace Microsoft.Net.Http.Headers
             Assert.True(CookieHeaderValue.TryParse(expectedValue, out var header));
 
             Assert.Equal(cookie, header);
-            Assert.Equal(expectedValue, header.ToString());
+            Assert.Equal(expectedValue, header!.ToString());
         }
 
         [Theory]

+ 2 - 2
src/Http/Headers/test/DateParserTest.cs

@@ -35,9 +35,9 @@ namespace Microsoft.Net.Http.Headers
             Assert.Equal(new DateTimeOffset(), result);
         }
 
-        public static IEnumerable<object[]> InvalidStringData()
+        public static IEnumerable<object?[]> InvalidStringData()
         {
-            yield return new object[] { null };
+            yield return new object?[] { null };
             yield return new object[] { string.Empty };
             yield return new object[] { "  " };
             yield return new object[] { "!!Sunday, 06-Nov-94 08:49:37 GMT" };

+ 12 - 19
src/Http/Headers/test/EntityTagHeaderValueTest.cs

@@ -92,7 +92,7 @@ namespace Microsoft.Net.Http.Headers
             Assert.False(etag1.Equals(etag2), "Different casing.");
             Assert.False(etag2.Equals(etag1), "Different casing.");
             Assert.False(etag1.Equals(null), "tag vs. <null>.");
-            Assert.False(etag1.Equals(etag3), "strong vs. weak.");
+            Assert.False(etag1!.Equals(etag3), "strong vs. weak.");
             Assert.False(etag3.Equals(etag1), "weak vs. strong.");
             Assert.False(etag1.Equals(etag4), "tag vs. tag1.");
             Assert.False(etag1.Equals(etag6), "tag vs. *.");
@@ -264,8 +264,7 @@ namespace Microsoft.Net.Http.Headers
         [Fact]
         public void TryParseList_NullOrEmptyArray_ReturnsFalse()
         {
-            IList<EntityTagHeaderValue> results = null;
-            Assert.False(EntityTagHeaderValue.TryParseList(null, out results));
+            Assert.False(EntityTagHeaderValue.TryParseList(null, out var results));
             Assert.False(EntityTagHeaderValue.TryParseList(new string[0], out results));
             Assert.False(EntityTagHeaderValue.TryParseList(new string[] { "" }, out results));
         }
@@ -351,8 +350,7 @@ namespace Microsoft.Net.Http.Headers
                 "\"tag\", \"tag\"",
                 "W/\"tag\"",
             };
-            IList<EntityTagHeaderValue> results;
-            Assert.True(EntityTagHeaderValue.TryParseList(inputs, out results));
+            Assert.True(EntityTagHeaderValue.TryParseList(inputs, out var results));
             var expectedResults = new[]
             {
                 new EntityTagHeaderValue("\"tag\""),
@@ -384,8 +382,7 @@ namespace Microsoft.Net.Http.Headers
                 "\"tag\", \"tag\"",
                 "W/\"tag\"",
             };
-            IList<EntityTagHeaderValue> results;
-            Assert.True(EntityTagHeaderValue.TryParseStrictList(inputs, out results));
+            Assert.True(EntityTagHeaderValue.TryParseStrictList(inputs, out var results));
             var expectedResults = new[]
             {
                 new EntityTagHeaderValue("\"tag\""),
@@ -465,8 +462,7 @@ namespace Microsoft.Net.Http.Headers
                 "\"tag\", \"tag\"",
                 "W/\"tag\"",
             };
-            IList<EntityTagHeaderValue> results;
-            Assert.True(EntityTagHeaderValue.TryParseList(inputs, out results));
+            Assert.True(EntityTagHeaderValue.TryParseList(inputs, out var results));
             var expectedResults = new[]
             {
                 new EntityTagHeaderValue("\"tag\""),
@@ -496,32 +492,29 @@ namespace Microsoft.Net.Http.Headers
                 "\"tag\", \"tag\"",
                 "W/\"tag\"",
             };
-            IList<EntityTagHeaderValue> results;
-            Assert.False(EntityTagHeaderValue.TryParseStrictList(inputs, out results));
+            Assert.False(EntityTagHeaderValue.TryParseStrictList(inputs, out var results));
         }
 
-        private void CheckValidParse(string input, EntityTagHeaderValue expectedResult)
+        private void CheckValidParse(string? input, EntityTagHeaderValue expectedResult)
         {
             var result = EntityTagHeaderValue.Parse(input);
             Assert.Equal(expectedResult, result);
         }
 
-        private void CheckInvalidParse(string input)
+        private void CheckInvalidParse(string? input)
         {
             Assert.Throws<FormatException>(() => EntityTagHeaderValue.Parse(input));
         }
 
-        private void CheckValidTryParse(string input, EntityTagHeaderValue expectedResult)
+        private void CheckValidTryParse(string? input, EntityTagHeaderValue expectedResult)
         {
-            EntityTagHeaderValue result = null;
-            Assert.True(EntityTagHeaderValue.TryParse(input, out result));
+            Assert.True(EntityTagHeaderValue.TryParse(input, out var result));
             Assert.Equal(expectedResult, result);
         }
 
-        private void CheckInvalidTryParse(string input)
+        private void CheckInvalidTryParse(string? input)
         {
-            EntityTagHeaderValue result = null;
-            Assert.False(EntityTagHeaderValue.TryParse(input, out result));
+            Assert.False(EntityTagHeaderValue.TryParse(input, out var result));
             Assert.Null(result);
         }
 

+ 15 - 22
src/Http/Headers/test/MediaTypeHeaderValueTest.cs

@@ -40,8 +40,8 @@ namespace Microsoft.Net.Http.Headers
             AssertFormatException("text/plain;charset=utf-8"); // ctor takes only media-type name, no parameters
         }
 
-        public static TheoryData<string, string, string> MediaTypesWithSuffixes =>
-                 new TheoryData<string, string, string>
+        public static TheoryData<string, string, string?> MediaTypesWithSuffixes =>
+                 new TheoryData<string, string, string?>
                  {
                      // See https://tools.ietf.org/html/rfc6838#section-4.2 for allowed names spec
                      { "application/json", "json", null },
@@ -124,7 +124,7 @@ namespace Microsoft.Net.Http.Headers
         public void Parameters_AddNull_Throw()
         {
             var mediaType = new MediaTypeHeaderValue("text/plain");
-            Assert.Throws<ArgumentNullException>(() => mediaType.Parameters.Add(null));
+            Assert.Throws<ArgumentNullException>(() => mediaType.Parameters.Add(null!));
         }
 
         [Fact]
@@ -381,7 +381,7 @@ namespace Microsoft.Net.Http.Headers
             Assert.False(mediaType1.Equals(mediaType2), "No params vs. charset.");
             Assert.False(mediaType2.Equals(mediaType1), "charset vs. no params.");
             Assert.False(mediaType1.Equals(null), "No params vs. <null>.");
-            Assert.False(mediaType1.Equals(mediaType3), "No params vs. custom param.");
+            Assert.False(mediaType1!.Equals(mediaType3), "No params vs. custom param.");
             Assert.False(mediaType2.Equals(mediaType3), "charset vs. custom param.");
             Assert.True(mediaType1.Equals(mediaType4), "Different casing.");
             Assert.True(mediaType2.Equals(mediaType5), "Different casing in charset.");
@@ -536,8 +536,7 @@ namespace Microsoft.Net.Http.Headers
         [Fact]
         public void TryParseList_NullOrEmptyArray_ReturnsFalse()
         {
-            IList<MediaTypeHeaderValue> results;
-            Assert.False(MediaTypeHeaderValue.TryParseList(null, out results));
+            Assert.False(MediaTypeHeaderValue.TryParseList(null, out var results));
             Assert.False(MediaTypeHeaderValue.TryParseList(new string[0], out results));
             Assert.False(MediaTypeHeaderValue.TryParseList(new string[] { "" }, out results));
         }
@@ -582,8 +581,7 @@ namespace Microsoft.Net.Http.Headers
         public void TryParseList_SetOfValidValueStrings_ReturnsTrue()
         {
             var inputs = new[] { "text/html,application/xhtml+xml,", "application/xml;q=0.9,image/webp,*/*;q=0.8" };
-            IList<MediaTypeHeaderValue> results;
-            Assert.True(MediaTypeHeaderValue.TryParseList(inputs, out results));
+            Assert.True(MediaTypeHeaderValue.TryParseList(inputs, out var results));
 
             var expectedResults = new[]
             {
@@ -601,8 +599,7 @@ namespace Microsoft.Net.Http.Headers
         public void TryParseStrictList_SetOfValidValueStrings_ReturnsTrue()
         {
             var inputs = new[] { "text/html,application/xhtml+xml,", "application/xml;q=0.9,image/webp,*/*;q=0.8" };
-            IList<MediaTypeHeaderValue> results;
-            Assert.True(MediaTypeHeaderValue.TryParseStrictList(inputs, out results));
+            Assert.True(MediaTypeHeaderValue.TryParseStrictList(inputs, out var results));
 
             var expectedResults = new[]
             {
@@ -659,8 +656,7 @@ namespace Microsoft.Net.Http.Headers
                 "application/xml;q=0.9,image/webp,*/*;q=0.8",
                 "application/xml;q=0 4"
             };
-            IList<MediaTypeHeaderValue> results;
-            Assert.True(MediaTypeHeaderValue.TryParseList(inputs, out results));
+            Assert.True(MediaTypeHeaderValue.TryParseList(inputs, out var results));
 
             var expectedResults = new[]
             {
@@ -684,8 +680,7 @@ namespace Microsoft.Net.Http.Headers
                 "application/xml;q=0.9,image/webp,*/*;q=0.8",
                 "application/xml;q=0 4"
             };
-            IList<MediaTypeHeaderValue> results;
-            Assert.False(MediaTypeHeaderValue.TryParseStrictList(inputs, out results));
+            Assert.False(MediaTypeHeaderValue.TryParseStrictList(inputs, out var results));
         }
 
         [Theory]
@@ -817,28 +812,26 @@ namespace Microsoft.Net.Http.Headers
             Assert.Equal(expected, result);
         }
 
-        private void CheckValidParse(string input, MediaTypeHeaderValue expectedResult)
+        private void CheckValidParse(string? input, MediaTypeHeaderValue expectedResult)
         {
             var result = MediaTypeHeaderValue.Parse(input);
             Assert.Equal(expectedResult, result);
         }
 
-        private void CheckInvalidParse(string input)
+        private void CheckInvalidParse(string? input)
         {
             Assert.Throws<FormatException>(() => MediaTypeHeaderValue.Parse(input));
         }
 
-        private void CheckValidTryParse(string input, MediaTypeHeaderValue expectedResult)
+        private void CheckValidTryParse(string? input, MediaTypeHeaderValue expectedResult)
         {
-            MediaTypeHeaderValue result = null;
-            Assert.True(MediaTypeHeaderValue.TryParse(input, out result));
+            Assert.True(MediaTypeHeaderValue.TryParse(input, out var result));
             Assert.Equal(expectedResult, result);
         }
 
-        private void CheckInvalidTryParse(string input)
+        private void CheckInvalidTryParse(string? input)
         {
-            MediaTypeHeaderValue result = null;
-            Assert.False(MediaTypeHeaderValue.TryParse(input, out result));
+            Assert.False(MediaTypeHeaderValue.TryParse(input, out var result));
             Assert.Null(result);
         }
 

+ 1 - 0
src/Http/Headers/test/Microsoft.Net.Http.Headers.Tests.csproj

@@ -2,6 +2,7 @@
 
   <PropertyGroup>
     <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
+    <Nullable>enable</Nullable>
   </PropertyGroup>
 
   <ItemGroup>

+ 13 - 19
src/Http/Headers/test/NameValueHeaderValueTest.cs

@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System;
@@ -412,8 +412,7 @@ namespace Microsoft.Net.Http.Headers
                 "name=value6,name=value7",
                 "name=\"value 8\", name= \"value 9\"",
             };
-            IList<NameValueHeaderValue> results;
-            Assert.True(NameValueHeaderValue.TryParseList(inputs, out results));
+            Assert.True(NameValueHeaderValue.TryParseList(inputs, out var results));
 
             var expectedResults = new[]
             {
@@ -446,8 +445,7 @@ namespace Microsoft.Net.Http.Headers
                 "name=value6,name=value7",
                 "name=\"value 8\", name= \"value 9\"",
             };
-            IList<NameValueHeaderValue> results;
-            Assert.True(NameValueHeaderValue.TryParseStrictList(inputs, out results));
+            Assert.True(NameValueHeaderValue.TryParseStrictList(inputs, out var results));
 
             var expectedResults = new[]
             {
@@ -534,8 +532,7 @@ namespace Microsoft.Net.Http.Headers
                 "name8=value8,name9=value9",
                 "name10=\"value 10\", name11= \"value 11\"",
             };
-            IList<NameValueHeaderValue> results;
-            Assert.True(NameValueHeaderValue.TryParseList(inputs, out results));
+            Assert.True(NameValueHeaderValue.TryParseList(inputs, out var results));
 
             var expectedResults = new[]
             {
@@ -571,8 +568,7 @@ namespace Microsoft.Net.Http.Headers
                 "name8=value8,name9=value9",
                 "name10=\"value 10\", name11= \"value 11\"",
             };
-            IList<NameValueHeaderValue> results;
-            Assert.False(NameValueHeaderValue.TryParseStrictList(inputs, out results));
+            Assert.False(NameValueHeaderValue.TryParseStrictList(inputs, out var results));
         }
 
         [Theory]
@@ -658,38 +654,36 @@ namespace Microsoft.Net.Http.Headers
 
         #region Helper methods
 
-        private void CheckValidParse(string input, NameValueHeaderValue expectedResult)
+        private void CheckValidParse(string? input, NameValueHeaderValue expectedResult)
         {
             var result = NameValueHeaderValue.Parse(input);
             Assert.Equal(expectedResult, result);
         }
 
-        private void CheckInvalidParse(string input)
+        private void CheckInvalidParse(string? input)
         {
             Assert.Throws<FormatException>(() => NameValueHeaderValue.Parse(input));
         }
 
-        private void CheckValidTryParse(string input, NameValueHeaderValue expectedResult)
+        private void CheckValidTryParse(string? input, NameValueHeaderValue expectedResult)
         {
-            NameValueHeaderValue result = null;
-            Assert.True(NameValueHeaderValue.TryParse(input, out result));
+            Assert.True(NameValueHeaderValue.TryParse(input, out var result));
             Assert.Equal(expectedResult, result);
         }
 
-        private void CheckInvalidTryParse(string input)
+        private void CheckInvalidTryParse(string? input)
         {
-            NameValueHeaderValue result = null;
-            Assert.False(NameValueHeaderValue.TryParse(input, out result));
+            Assert.False(NameValueHeaderValue.TryParse(input, out var result));
             Assert.Null(result);
         }
 
-        private static void CheckValue(string value)
+        private static void CheckValue(string? value)
         {
             var nameValue = new NameValueHeaderValue("text", value);
             Assert.Equal(value, nameValue.Value);
         }
 
-        private static void AssertFormatException(string name, string value)
+        private static void AssertFormatException(string name, string? value)
         {
             Assert.Throws<FormatException>(() => new NameValueHeaderValue(name, value));
         }

+ 5 - 7
src/Http/Headers/test/RangeConditionHeaderValueTest.cs

@@ -15,7 +15,7 @@ namespace Microsoft.Net.Http.Headers
             Assert.Equal(new EntityTagHeaderValue("\"x\""), rangeCondition.EntityTag);
             Assert.Null(rangeCondition.LastModified);
 
-            EntityTagHeaderValue input = null;
+            EntityTagHeaderValue input = null!;
             Assert.Throws<ArgumentNullException>(() => new RangeConditionHeaderValue(input));
         }
 
@@ -26,7 +26,7 @@ namespace Microsoft.Net.Http.Headers
             Assert.Equal(new EntityTagHeaderValue("\"y\""), rangeCondition.EntityTag);
             Assert.Null(rangeCondition.LastModified);
 
-            Assert.Throws<ArgumentException>(() => new RangeConditionHeaderValue((string)null));
+            Assert.Throws<ArgumentException>(() => new RangeConditionHeaderValue((string?)null));
         }
 
         [Fact]
@@ -84,7 +84,7 @@ namespace Microsoft.Net.Http.Headers
                 new EntityTagHeaderValue("\"x\"", true));
 
             Assert.False(rangeCondition1.Equals(null), "\"x\" vs. <null>");
-            Assert.True(rangeCondition1.Equals(rangeCondition2), "\"x\" vs. \"x\"");
+            Assert.True(rangeCondition1!.Equals(rangeCondition2), "\"x\" vs. \"x\"");
             Assert.False(rangeCondition1.Equals(rangeCondition3), "\"x\" vs. date");
             Assert.False(rangeCondition3.Equals(rangeCondition1), "date vs. \"x\"");
             Assert.False(rangeCondition3.Equals(rangeCondition4), "date vs. different date");
@@ -149,8 +149,7 @@ namespace Microsoft.Net.Http.Headers
         [InlineData("Wed 09 Nov 1994 08:49:37 GMT,")]
         public void TryParse_SetOfInvalidValueStrings_ReturnsFalse(string input)
         {
-            RangeConditionHeaderValue result = null;
-            Assert.False(RangeConditionHeaderValue.TryParse(input, out result));
+            Assert.False(RangeConditionHeaderValue.TryParse(input, out var result));
             Assert.Null(result);
         }
 
@@ -164,8 +163,7 @@ namespace Microsoft.Net.Http.Headers
 
         private void CheckValidTryParse(string input, RangeConditionHeaderValue expectedResult)
         {
-            RangeConditionHeaderValue result = null;
-            Assert.True(RangeConditionHeaderValue.TryParse(input, out result));
+            Assert.True(RangeConditionHeaderValue.TryParse(input, out var result));
             Assert.Equal(expectedResult, result);
         }
 

+ 7 - 9
src/Http/Headers/test/RangeHeaderValueTest.cs

@@ -82,7 +82,7 @@ namespace Microsoft.Net.Http.Headers
             range7.Unit = "other";
 
             Assert.False(range1.Equals(null), "bytes=1-2 vs. <null>");
-            Assert.True(range1.Equals(range2), "bytes=1-2 vs. BYTES=1-2");
+            Assert.True(range1!.Equals(range2), "bytes=1-2 vs. BYTES=1-2");
             Assert.False(range1.Equals(range3), "bytes=1-2 vs. bytes=1-");
             Assert.False(range1.Equals(range4), "bytes=1-2 vs. bytes=-2");
             Assert.False(range1.Equals(range5), "bytes=1-2 vs. bytes=1-2,3-4");
@@ -153,28 +153,26 @@ namespace Microsoft.Net.Http.Headers
 
         #region Helper methods
 
-        private void CheckValidParse(string input, RangeHeaderValue expectedResult)
+        private void CheckValidParse(string? input, RangeHeaderValue expectedResult)
         {
             var result = RangeHeaderValue.Parse(input);
             Assert.Equal(expectedResult, result);
         }
 
-        private void CheckInvalidParse(string input)
+        private void CheckInvalidParse(string? input)
         {
             Assert.Throws<FormatException>(() => RangeHeaderValue.Parse(input));
         }
 
-        private void CheckValidTryParse(string input, RangeHeaderValue expectedResult)
+        private void CheckValidTryParse(string? input, RangeHeaderValue expectedResult)
         {
-            RangeHeaderValue result = null;
-            Assert.True(RangeHeaderValue.TryParse(input, out result));
+            Assert.True(RangeHeaderValue.TryParse(input, out var result));
             Assert.Equal(expectedResult, result);
         }
 
-        private void CheckInvalidTryParse(string input)
+        private void CheckInvalidTryParse(string? input)
         {
-            RangeHeaderValue result = null;
-            Assert.False(RangeHeaderValue.TryParse(input, out result));
+            Assert.False(RangeHeaderValue.TryParse(input, out var result));
             Assert.Null(result);
         }
 

+ 1 - 1
src/Http/Headers/test/RangeItemHeaderValueTest.cs

@@ -83,7 +83,7 @@ namespace Microsoft.Net.Http.Headers
             Assert.False(rangeItem1.Equals(rangeItem2), "1-2 vs. 1-.");
             Assert.False(rangeItem2.Equals(rangeItem1), "1- vs. 1-2.");
             Assert.False(rangeItem1.Equals(null), "1-2 vs. null.");
-            Assert.False(rangeItem1.Equals(rangeItem3), "1-2 vs. -2.");
+            Assert.False(rangeItem1!.Equals(rangeItem3), "1-2 vs. -2.");
             Assert.False(rangeItem3.Equals(rangeItem1), "-2 vs. 1-2.");
             Assert.False(rangeItem1.Equals(rangeItem4), "1-2 vs. 2-2.");
             Assert.True(rangeItem1.Equals(rangeItem5), "1-2 vs. 1-2.");

+ 7 - 9
src/Http/Headers/test/SetCookieHeaderValueTest.cs

@@ -111,11 +111,11 @@ namespace Microsoft.Net.Http.Headers
             }
         }
 
-        public static TheoryData<IList<SetCookieHeaderValue>, string[]> ListOfSetCookieHeaderDataSet
+        public static TheoryData<IList<SetCookieHeaderValue>, string?[]> ListOfSetCookieHeaderDataSet
         {
             get
             {
-                var dataset = new TheoryData<IList<SetCookieHeaderValue>, string[]>();
+                var dataset = new TheoryData<IList<SetCookieHeaderValue>, string?[]>();
                 var header1 = new SetCookieHeaderValue("name1", "n1=v1&n2=v2&n3=v3")
                 {
                     Domain = "domain1",
@@ -190,11 +190,11 @@ namespace Microsoft.Net.Http.Headers
             }
         }
 
-        public static TheoryData<IList<SetCookieHeaderValue>, string[]> ListWithInvalidSetCookieHeaderDataSet
+        public static TheoryData<IList<SetCookieHeaderValue>?, string?[]> ListWithInvalidSetCookieHeaderDataSet
         {
             get
             {
-                var dataset = new TheoryData<IList<SetCookieHeaderValue>, string[]>();
+                var dataset = new TheoryData<IList<SetCookieHeaderValue>?, string?[]>();
                 var header1 = new SetCookieHeaderValue("name1", "n1=v1&n2=v2&n3=v3")
                 {
                     Domain = "domain1",
@@ -341,7 +341,7 @@ namespace Microsoft.Net.Http.Headers
             Assert.True(SetCookieHeaderValue.TryParse(expectedValue, out var header));
 
             Assert.Equal(cookie, header);
-            Assert.Equal(expectedValue, header.ToString());
+            Assert.Equal(expectedValue, header!.ToString());
         }
 
         [Theory]
@@ -382,11 +382,9 @@ namespace Microsoft.Net.Http.Headers
         {
             string cookieHeaderValue = "cookiename=value; extensionname=value;";
 
-            SetCookieHeaderValue setCookieHeaderValue;
-
-            SetCookieHeaderValue.TryParse(cookieHeaderValue, out setCookieHeaderValue);
 
-            Assert.Equal("value", setCookieHeaderValue.Value);
+            SetCookieHeaderValue.TryParse(cookieHeaderValue, out var setCookieHeaderValue);
+            Assert.Equal("value", setCookieHeaderValue!.Value);
         }
 
         [Theory]

+ 10 - 16
src/Http/Headers/test/StringWithQualityHeaderValueTest.cs

@@ -94,7 +94,7 @@ namespace Microsoft.Net.Http.Headers
             var value9 = new StringWithQualityHeaderValue("x");
 
             Assert.False(value1.Equals(null), "t; q=0.123 vs. <null>");
-            Assert.True(value1.Equals(value2), "t; q=0.123 vs. t; q=0.123");
+            Assert.True(value1!.Equals(value2), "t; q=0.123 vs. t; q=0.123");
             Assert.True(value1.Equals(value3), "t; q=0.123 vs. T; q=0.123");
             Assert.False(value1.Equals(value4), "t; q=0.123 vs. t");
             Assert.False(value4.Equals(value1), "t vs. t; q=0.123");
@@ -293,8 +293,7 @@ namespace Microsoft.Net.Http.Headers
                 "text7,text8;q=0.5",
                 " text9 , text10 ; q = 0.5 ",
             };
-            IList<StringWithQualityHeaderValue> results;
-            Assert.True(StringWithQualityHeaderValue.TryParseList(inputs, out results));
+            Assert.True(StringWithQualityHeaderValue.TryParseList(inputs, out var results));
 
             var expectedResults = new[]
             {
@@ -331,8 +330,7 @@ namespace Microsoft.Net.Http.Headers
                 "text7,text8;q=0.5",
                 " text9 , text10 ; q = 0.5 ",
             };
-            IList<StringWithQualityHeaderValue> results;
-            Assert.True(StringWithQualityHeaderValue.TryParseStrictList(inputs, out results));
+            Assert.True(StringWithQualityHeaderValue.TryParseStrictList(inputs, out var results));
 
             var expectedResults = new[]
             {
@@ -428,8 +426,7 @@ namespace Microsoft.Net.Http.Headers
                 "text7,text8;q=0.5",
                 " text9 , text10 ; q = 0.5 ",
             };
-            IList<StringWithQualityHeaderValue> results;
-            Assert.True(StringWithQualityHeaderValue.TryParseList(inputs, out results));
+            Assert.True(StringWithQualityHeaderValue.TryParseList(inputs, out var results));
 
             var expectedResults = new[]
             {
@@ -467,29 +464,26 @@ namespace Microsoft.Net.Http.Headers
                 "text7,text8;q=0.5",
                 " text9 , text10 ; q = 0.5 ",
             };
-            IList<StringWithQualityHeaderValue> results;
-            Assert.False(StringWithQualityHeaderValue.TryParseStrictList(inputs, out results));
+            Assert.False(StringWithQualityHeaderValue.TryParseStrictList(inputs, out var results));
         }
 
         #region Helper methods
 
-        private void CheckValidParse(string input, StringWithQualityHeaderValue expectedResult)
+        private void CheckValidParse(string? input, StringWithQualityHeaderValue expectedResult)
         {
             var result = StringWithQualityHeaderValue.Parse(input);
             Assert.Equal(expectedResult, result);
         }
 
-        private void CheckValidTryParse(string input, StringWithQualityHeaderValue expectedResult)
+        private void CheckValidTryParse(string? input, StringWithQualityHeaderValue expectedResult)
         {
-            StringWithQualityHeaderValue result = null;
-            Assert.True(StringWithQualityHeaderValue.TryParse(input, out result));
+            Assert.True(StringWithQualityHeaderValue.TryParse(input, out var result));
             Assert.Equal(expectedResult, result);
         }
 
-        private void CheckInvalidTryParse(string input)
+        private void CheckInvalidTryParse(string? input)
         {
-            StringWithQualityHeaderValue result = null;
-            Assert.False(StringWithQualityHeaderValue.TryParse(input, out result));
+            Assert.False(StringWithQualityHeaderValue.TryParse(input, out var result));
             Assert.Null(result);
         }
 

+ 1 - 0
src/Http/Http.Abstractions/ref/Microsoft.AspNetCore.Http.Abstractions.csproj

@@ -2,6 +2,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <TargetFrameworks>$(DefaultNetCoreTargetFramework)</TargetFrameworks>
+    <Nullable>annotations</Nullable>
   </PropertyGroup>
   <ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'">
     <Compile Include="Microsoft.AspNetCore.Http.Abstractions.netcoreapp.cs" />

+ 47 - 47
src/Http/Http.Abstractions/ref/Microsoft.AspNetCore.Http.Abstractions.netcoreapp.cs

@@ -6,9 +6,9 @@ namespace Microsoft.AspNetCore.Builder
     public abstract partial class EndpointBuilder
     {
         protected EndpointBuilder() { }
-        public string DisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
+        public string? DisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public System.Collections.Generic.IList<object> Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
-        public Microsoft.AspNetCore.Http.RequestDelegate RequestDelegate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
+        public Microsoft.AspNetCore.Http.RequestDelegate? RequestDelegate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public abstract Microsoft.AspNetCore.Http.Endpoint Build();
     }
     public partial interface IApplicationBuilder
@@ -66,7 +66,7 @@ namespace Microsoft.AspNetCore.Builder.Extensions
     public partial class MapOptions
     {
         public MapOptions() { }
-        public Microsoft.AspNetCore.Http.RequestDelegate Branch { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
+        public Microsoft.AspNetCore.Http.RequestDelegate? Branch { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public Microsoft.AspNetCore.Http.PathString PathMatch { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public bool PreserveMatchedPathSegment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
     }
@@ -79,8 +79,8 @@ namespace Microsoft.AspNetCore.Builder.Extensions
     public partial class MapWhenOptions
     {
         public MapWhenOptions() { }
-        public Microsoft.AspNetCore.Http.RequestDelegate Branch { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
-        public System.Func<Microsoft.AspNetCore.Http.HttpContext, bool> Predicate { get { throw null; } set { } }
+        public Microsoft.AspNetCore.Http.RequestDelegate? Branch { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
+        public System.Func<Microsoft.AspNetCore.Http.HttpContext, bool>? Predicate { get { throw null; } set { } }
     }
     public partial class UsePathBaseMiddleware
     {
@@ -119,13 +119,13 @@ namespace Microsoft.AspNetCore.Http
     public partial class CookieBuilder
     {
         public CookieBuilder() { }
-        public virtual string Domain { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
+        public virtual string? Domain { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public virtual System.TimeSpan? Expiration { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public virtual bool HttpOnly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public virtual bool IsEssential { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public virtual System.TimeSpan? MaxAge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
-        public virtual string Name { get { throw null; } set { } }
-        public virtual string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
+        public virtual string? Name { get { throw null; } set { } }
+        public virtual string? Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public virtual Microsoft.AspNetCore.Http.SameSiteMode SameSite { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public virtual Microsoft.AspNetCore.Http.CookieSecurePolicy SecurePolicy { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public Microsoft.AspNetCore.Http.CookieOptions Build(Microsoft.AspNetCore.Http.HttpContext context) { throw null; }
@@ -143,12 +143,12 @@ namespace Microsoft.AspNetCore.Http
         public string DisplayName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
         public Microsoft.AspNetCore.Http.EndpointMetadataCollection Metadata { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
         public Microsoft.AspNetCore.Http.RequestDelegate RequestDelegate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
-        public override string ToString() { throw null; }
+        public override string? ToString() { throw null; }
     }
     public static partial class EndpointHttpContextExtensions
     {
-        public static Microsoft.AspNetCore.Http.Endpoint GetEndpoint(this Microsoft.AspNetCore.Http.HttpContext context) { throw null; }
-        public static void SetEndpoint(this Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Http.Endpoint endpoint) { }
+        public static Microsoft.AspNetCore.Http.Endpoint? GetEndpoint(this Microsoft.AspNetCore.Http.HttpContext context) { throw null; }
+        public static void SetEndpoint(this Microsoft.AspNetCore.Http.HttpContext context, Microsoft.AspNetCore.Http.Endpoint? endpoint) { }
     }
     public sealed partial class EndpointMetadataCollection : System.Collections.Generic.IEnumerable<object>, System.Collections.Generic.IReadOnlyCollection<object>, System.Collections.Generic.IReadOnlyList<object>, System.Collections.IEnumerable
     {
@@ -158,16 +158,16 @@ namespace Microsoft.AspNetCore.Http
         public int Count { get { throw null; } }
         public object this[int index] { get { throw null; } }
         public Microsoft.AspNetCore.Http.EndpointMetadataCollection.Enumerator GetEnumerator() { throw null; }
-        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public T GetMetadata<T>() where T : class { throw null; }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public T? GetMetadata<T>() where T : class { throw null; }
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public System.Collections.Generic.IReadOnlyList<T> GetOrderedMetadata<T>() where T : class { throw null; }
-        System.Collections.Generic.IEnumerator<object> System.Collections.Generic.IEnumerable<System.Object>.GetEnumerator() { throw null; }
+        System.Collections.Generic.IEnumerator<object> System.Collections.Generic.IEnumerable<object>.GetEnumerator() { throw null; }
         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
         [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
-        public partial struct Enumerator : System.Collections.Generic.IEnumerator<object>, System.Collections.IEnumerator, System.IDisposable
+        public partial struct Enumerator : System.Collections.Generic.IEnumerator<object?>, System.Collections.IEnumerator, System.IDisposable
         {
             private object _dummy;
             private int _dummyPrimitive;
-            public object Current { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
+            public object? Current { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
             public void Dispose() { }
             public bool MoveNext() { throw null; }
             public void Reset() { }
@@ -183,7 +183,7 @@ namespace Microsoft.AspNetCore.Http
         public bool HasValue { get { throw null; } }
         public string Value { get { throw null; } }
         public bool Equals(Microsoft.AspNetCore.Http.FragmentString other) { throw null; }
-        public override bool Equals(object obj) { throw null; }
+        public override bool Equals(object? obj) { throw null; }
         public static Microsoft.AspNetCore.Http.FragmentString FromUriComponent(string uriComponent) { throw null; }
         public static Microsoft.AspNetCore.Http.FragmentString FromUriComponent(System.Uri uri) { throw null; }
         public override int GetHashCode() { throw null; }
@@ -211,7 +211,7 @@ namespace Microsoft.AspNetCore.Http
         public int? Port { get { throw null; } }
         public string Value { get { throw null; } }
         public bool Equals(Microsoft.AspNetCore.Http.HostString other) { throw null; }
-        public override bool Equals(object obj) { throw null; }
+        public override bool Equals(object? obj) { throw null; }
         public static Microsoft.AspNetCore.Http.HostString FromUriComponent(string uriComponent) { throw null; }
         public static Microsoft.AspNetCore.Http.HostString FromUriComponent(System.Uri uri) { throw null; }
         public override int GetHashCode() { throw null; }
@@ -226,12 +226,12 @@ namespace Microsoft.AspNetCore.Http
         protected HttpContext() { }
         public abstract Microsoft.AspNetCore.Http.ConnectionInfo Connection { get; }
         public abstract Microsoft.AspNetCore.Http.Features.IFeatureCollection Features { get; }
-        public abstract System.Collections.Generic.IDictionary<object, object> Items { get; set; }
+        public abstract System.Collections.Generic.IDictionary<object, object?> Items { get; set; }
         public abstract Microsoft.AspNetCore.Http.HttpRequest Request { get; }
         public abstract System.Threading.CancellationToken RequestAborted { get; set; }
         public abstract System.IServiceProvider RequestServices { get; set; }
         public abstract Microsoft.AspNetCore.Http.HttpResponse Response { get; }
-        public abstract Microsoft.AspNetCore.Http.ISession Session { get; set; }
+        public abstract Microsoft.AspNetCore.Http.ISession? Session { get; set; }
         public abstract string TraceIdentifier { get; set; }
         public abstract System.Security.Claims.ClaimsPrincipal User { get; set; }
         public abstract Microsoft.AspNetCore.Http.WebSocketManager WebSockets { get; }
@@ -339,7 +339,7 @@ namespace Microsoft.AspNetCore.Http
     }
     public partial interface IMiddlewareFactory
     {
-        Microsoft.AspNetCore.Http.IMiddleware Create(System.Type middlewareType);
+        Microsoft.AspNetCore.Http.IMiddleware? Create(System.Type middlewareType);
         void Release(Microsoft.AspNetCore.Http.IMiddleware middleware);
     }
     [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
@@ -348,14 +348,14 @@ namespace Microsoft.AspNetCore.Http
         private readonly object _dummy;
         private readonly int _dummyPrimitive;
         public static readonly Microsoft.AspNetCore.Http.PathString Empty;
-        public PathString(string value) { throw null; }
+        public PathString(string? value) { throw null; }
         public bool HasValue { get { throw null; } }
-        public string Value { get { throw null; } }
+        public string? Value { get { throw null; } }
         public Microsoft.AspNetCore.Http.PathString Add(Microsoft.AspNetCore.Http.PathString other) { throw null; }
         public string Add(Microsoft.AspNetCore.Http.QueryString other) { throw null; }
         public bool Equals(Microsoft.AspNetCore.Http.PathString other) { throw null; }
         public bool Equals(Microsoft.AspNetCore.Http.PathString other, System.StringComparison comparisonType) { throw null; }
-        public override bool Equals(object obj) { throw null; }
+        public override bool Equals(object? obj) { throw null; }
         public static Microsoft.AspNetCore.Http.PathString FromUriComponent(string uriComponent) { throw null; }
         public static Microsoft.AspNetCore.Http.PathString FromUriComponent(System.Uri uri) { throw null; }
         public override int GetHashCode() { throw null; }
@@ -365,7 +365,7 @@ namespace Microsoft.AspNetCore.Http
         public static string operator +(string left, Microsoft.AspNetCore.Http.PathString right) { throw null; }
         public static bool operator ==(Microsoft.AspNetCore.Http.PathString left, Microsoft.AspNetCore.Http.PathString right) { throw null; }
         public static implicit operator string (Microsoft.AspNetCore.Http.PathString path) { throw null; }
-        public static implicit operator Microsoft.AspNetCore.Http.PathString (string s) { throw null; }
+        public static implicit operator Microsoft.AspNetCore.Http.PathString (string? s) { throw null; }
         public static bool operator !=(Microsoft.AspNetCore.Http.PathString left, Microsoft.AspNetCore.Http.PathString right) { throw null; }
         public bool StartsWithSegments(Microsoft.AspNetCore.Http.PathString other) { throw null; }
         public bool StartsWithSegments(Microsoft.AspNetCore.Http.PathString other, out Microsoft.AspNetCore.Http.PathString remaining) { throw null; }
@@ -382,16 +382,16 @@ namespace Microsoft.AspNetCore.Http
         private readonly object _dummy;
         private readonly int _dummyPrimitive;
         public static readonly Microsoft.AspNetCore.Http.QueryString Empty;
-        public QueryString(string value) { throw null; }
+        public QueryString(string? value) { throw null; }
         public bool HasValue { get { throw null; } }
-        public string Value { get { throw null; } }
+        public string? Value { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
         public Microsoft.AspNetCore.Http.QueryString Add(Microsoft.AspNetCore.Http.QueryString other) { throw null; }
         public Microsoft.AspNetCore.Http.QueryString Add(string name, string value) { throw null; }
         public static Microsoft.AspNetCore.Http.QueryString Create(System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>> parameters) { throw null; }
-        public static Microsoft.AspNetCore.Http.QueryString Create(System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, string>> parameters) { throw null; }
+        public static Microsoft.AspNetCore.Http.QueryString Create(System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, string?>> parameters) { throw null; }
         public static Microsoft.AspNetCore.Http.QueryString Create(string name, string value) { throw null; }
         public bool Equals(Microsoft.AspNetCore.Http.QueryString other) { throw null; }
-        public override bool Equals(object obj) { throw null; }
+        public override bool Equals(object? obj) { throw null; }
         public static Microsoft.AspNetCore.Http.QueryString FromUriComponent(string uriComponent) { throw null; }
         public static Microsoft.AspNetCore.Http.QueryString FromUriComponent(System.Uri uri) { throw null; }
         public override int GetHashCode() { throw null; }
@@ -489,14 +489,14 @@ namespace Microsoft.AspNetCore.Http
         public abstract bool IsWebSocketRequest { get; }
         public abstract System.Collections.Generic.IList<string> WebSocketRequestedProtocols { get; }
         public virtual System.Threading.Tasks.Task<System.Net.WebSockets.WebSocket> AcceptWebSocketAsync() { throw null; }
-        public abstract System.Threading.Tasks.Task<System.Net.WebSockets.WebSocket> AcceptWebSocketAsync(string subProtocol);
+        public abstract System.Threading.Tasks.Task<System.Net.WebSockets.WebSocket> AcceptWebSocketAsync(string? subProtocol);
     }
 }
 namespace Microsoft.AspNetCore.Http.Features
 {
     public partial interface IEndpointFeature
     {
-        Microsoft.AspNetCore.Http.Endpoint Endpoint { get; set; }
+        Microsoft.AspNetCore.Http.Endpoint? Endpoint { get; set; }
     }
     public partial interface IRouteValuesFeature
     {
@@ -505,40 +505,40 @@ namespace Microsoft.AspNetCore.Http.Features
 }
 namespace Microsoft.AspNetCore.Routing
 {
-    public partial class RouteValueDictionary : System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<string, object>>, System.Collections.Generic.IDictionary<string, object>, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, object>>, System.Collections.Generic.IReadOnlyCollection<System.Collections.Generic.KeyValuePair<string, object>>, System.Collections.Generic.IReadOnlyDictionary<string, object>, System.Collections.IEnumerable
+    public partial class RouteValueDictionary : System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<string, object?>>, System.Collections.Generic.IDictionary<string, object?>, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, object?>>, System.Collections.Generic.IReadOnlyCollection<System.Collections.Generic.KeyValuePair<string, object?>>, System.Collections.Generic.IReadOnlyDictionary<string, object?>, System.Collections.IEnumerable
     {
         public RouteValueDictionary() { }
-        public RouteValueDictionary(object values) { }
+        public RouteValueDictionary(object? values) { }
         public System.Collections.Generic.IEqualityComparer<string> Comparer { get { throw null; } }
         public int Count { get { throw null; } }
-        public object this[string key] { get { throw null; } set { } }
+        public object? this[string key] { get { throw null; } set { } }
         public System.Collections.Generic.ICollection<string> Keys { get { throw null; } }
-        bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.String,System.Object>>.IsReadOnly { get { throw null; } }
-        System.Collections.Generic.IEnumerable<string> System.Collections.Generic.IReadOnlyDictionary<System.String,System.Object>.Keys { get { throw null; } }
-        System.Collections.Generic.IEnumerable<object> System.Collections.Generic.IReadOnlyDictionary<System.String,System.Object>.Values { get { throw null; } }
-        public System.Collections.Generic.ICollection<object> Values { get { throw null; } }
-        public void Add(string key, object value) { }
+        bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<string, object?>>.IsReadOnly { get { throw null; } }
+        System.Collections.Generic.IEnumerable<string> System.Collections.Generic.IReadOnlyDictionary<string, object?>.Keys { get { throw null; } }
+        System.Collections.Generic.IEnumerable<object?> System.Collections.Generic.IReadOnlyDictionary<string, object?>.Values { get { throw null; } }
+        public System.Collections.Generic.ICollection<object?> Values { get { throw null; } }
+        public void Add(string key, object? value) { }
         public void Clear() { }
         public bool ContainsKey(string key) { throw null; }
         public static Microsoft.AspNetCore.Routing.RouteValueDictionary FromArray(System.Collections.Generic.KeyValuePair<string, object>[] items) { throw null; }
         public Microsoft.AspNetCore.Routing.RouteValueDictionary.Enumerator GetEnumerator() { throw null; }
         public bool Remove(string key) { throw null; }
-        public bool Remove(string key, out object value) { throw null; }
-        void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.String,System.Object>>.Add(System.Collections.Generic.KeyValuePair<string, object> item) { }
-        bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.String,System.Object>>.Contains(System.Collections.Generic.KeyValuePair<string, object> item) { throw null; }
-        void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.String,System.Object>>.CopyTo(System.Collections.Generic.KeyValuePair<string, object>[] array, int arrayIndex) { }
-        bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<System.String,System.Object>>.Remove(System.Collections.Generic.KeyValuePair<string, object> item) { throw null; }
-        System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, object>> System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<System.String,System.Object>>.GetEnumerator() { throw null; }
+        public bool Remove(string key, out object? value) { throw null; }
+        void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<string, object?>>.Add(System.Collections.Generic.KeyValuePair<string, object?> item) { }
+        bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<string, object?>>.Contains(System.Collections.Generic.KeyValuePair<string, object?> item) { throw null; }
+        void System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<string, object?>>.CopyTo(System.Collections.Generic.KeyValuePair<string, object>[] array, int arrayIndex) { }
+        bool System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<string, object?>>.Remove(System.Collections.Generic.KeyValuePair<string, object?> item) { throw null; }
+        System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, object?>> System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, object?>>.GetEnumerator() { throw null; }
         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
         public bool TryAdd(string key, object value) { throw null; }
-        public bool TryGetValue(string key, out object value) { throw null; }
+        public bool TryGetValue(string key, out object? value) { throw null; }
         [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
-        public partial struct Enumerator : System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, object>>, System.Collections.IEnumerator, System.IDisposable
+        public partial struct Enumerator : System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, object?>>, System.Collections.IEnumerator, System.IDisposable
         {
             private object _dummy;
             private int _dummyPrimitive;
             public Enumerator(Microsoft.AspNetCore.Routing.RouteValueDictionary dictionary) { throw null; }
-            public System.Collections.Generic.KeyValuePair<string, object> Current { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
+            public System.Collections.Generic.KeyValuePair<string, object?> Current { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
             object System.Collections.IEnumerator.Current { get { throw null; } }
             public void Dispose() { }
             [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public bool MoveNext() { throw null; }

+ 4 - 4
src/Http/Http.Abstractions/src/CookieBuilder.cs

@@ -11,12 +11,12 @@ namespace Microsoft.AspNetCore.Http
     /// </summary>
     public class CookieBuilder
     {
-        private string _name;
+        private string? _name;
 
         /// <summary>
         /// The name of the cookie.
         /// </summary>
-        public virtual string Name
+        public virtual string? Name
         {
             get => _name;
             set => _name = !string.IsNullOrEmpty(value)
@@ -30,7 +30,7 @@ namespace Microsoft.AspNetCore.Http
         /// <remarks>
         /// Determines the value that will set on <see cref="CookieOptions.Path"/>.
         /// </remarks>
-        public virtual string Path { get; set; }
+        public virtual string? Path { get; set; }
 
         /// <summary>
         /// The domain to associate the cookie with.
@@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Http
         /// <remarks>
         /// Determines the value that will set on <see cref="CookieOptions.Domain"/>.
         /// </remarks>
-        public virtual string Domain { get; set; }
+        public virtual string? Domain { get; set; }
 
         /// <summary>
         /// Indicates whether a cookie is accessible by client-side script.

+ 2 - 2
src/Http/Http.Abstractions/src/Extensions/EndpointBuilder.cs

@@ -14,12 +14,12 @@ namespace Microsoft.AspNetCore.Builder
         /// <summary>
         /// Gets or sets the delegate used to process requests for the endpoint.
         /// </summary>
-        public RequestDelegate RequestDelegate { get; set; }
+        public RequestDelegate? RequestDelegate { get; set; }
 
         /// <summary>
         /// Gets or sets the informational display name of this endpoint.
         /// </summary>
-        public string DisplayName { get; set; }
+        public string? DisplayName { get; set; }
 
         /// <summary>
         /// Gets the collection of metadata associated with this endpoint.

+ 1 - 1
src/Http/Http.Abstractions/src/Extensions/MapExtensions.cs

@@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Builder
                 throw new ArgumentNullException(nameof(configuration));
             }
 
-            if (pathMatch.HasValue && pathMatch.Value.EndsWith("/", StringComparison.Ordinal))
+            if (pathMatch.HasValue && pathMatch.Value!.EndsWith("/", StringComparison.Ordinal))
             {
                 throw new ArgumentException("The path must not end with a '/'", nameof(pathMatch));
             }

+ 6 - 1
src/Http/Http.Abstractions/src/Extensions/MapMiddleware.cs

@@ -32,6 +32,11 @@ namespace Microsoft.AspNetCore.Builder.Extensions
                 throw new ArgumentNullException(nameof(options));
             }
 
+            if (options.Branch == null)
+            {
+                throw new ArgumentException("Branch not set on options.", nameof(options));
+            }
+
             _next = next;
             _options = options;
         }
@@ -62,7 +67,7 @@ namespace Microsoft.AspNetCore.Builder.Extensions
 
                 try
                 {
-                    await _options.Branch(context);
+                    await _options.Branch!(context);
                 }
                 finally
                 {

+ 1 - 1
src/Http/Http.Abstractions/src/Extensions/MapOptions.cs

@@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Builder.Extensions
         /// <summary>
         /// The branch taken for a positive match.
         /// </summary>
-        public RequestDelegate Branch { get; set; }
+        public RequestDelegate? Branch { get; set; }
 
         /// <summary>
         /// If false, matched path would be removed from Request.Path and added to Request.PathBase

+ 13 - 3
src/Http/Http.Abstractions/src/Extensions/MapWhenMiddleware.cs

@@ -32,6 +32,16 @@ namespace Microsoft.AspNetCore.Builder.Extensions
                 throw new ArgumentNullException(nameof(options));
             }
 
+            if (options.Predicate == null)
+            {
+                throw new ArgumentException("Predicate not set on options.", nameof(options));
+            }
+
+            if (options.Branch == null)
+            {
+                throw new ArgumentException("Branch not set on options.", nameof(options));
+            }
+
             _next = next;
             _options = options;
         }
@@ -48,9 +58,9 @@ namespace Microsoft.AspNetCore.Builder.Extensions
                 throw new ArgumentNullException(nameof(context));
             }
 
-            if (_options.Predicate(context))
+            if (_options.Predicate!(context))
             {
-                await _options.Branch(context);
+                await _options.Branch!(context);
             }
             else
             {
@@ -58,4 +68,4 @@ namespace Microsoft.AspNetCore.Builder.Extensions
             }
         }
     }
-}
+}

+ 4 - 4
src/Http/Http.Abstractions/src/Extensions/MapWhenOptions.cs

@@ -11,12 +11,12 @@ namespace Microsoft.AspNetCore.Builder.Extensions
     /// </summary>
     public class MapWhenOptions
     {
-        private Func<HttpContext, bool> _predicate;
+        private Func<HttpContext, bool>? _predicate;
 
         /// <summary>
         /// The user callback that determines if the branch should be taken.
         /// </summary>
-        public Func<HttpContext, bool> Predicate
+        public Func<HttpContext, bool>? Predicate
         {
             get
             {
@@ -36,6 +36,6 @@ namespace Microsoft.AspNetCore.Builder.Extensions
         /// <summary>
         /// The branch taken for a positive match.
         /// </summary>
-        public RequestDelegate Branch { get; set; }
+        public RequestDelegate? Branch { get; set; }
     }
-}
+}

+ 3 - 3
src/Http/Http.Abstractions/src/Extensions/UseMiddlewareExtensions.cs

@@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Builder
         internal const string InvokeMethodName = "Invoke";
         internal const string InvokeAsyncMethodName = "InvokeAsync";
 
-        private static readonly MethodInfo GetServiceInfo = typeof(UseMiddlewareExtensions).GetMethod(nameof(GetService), BindingFlags.NonPublic | BindingFlags.Static);
+        private static readonly MethodInfo GetServiceInfo = typeof(UseMiddlewareExtensions).GetMethod(nameof(GetService), BindingFlags.NonPublic | BindingFlags.Static)!;
 
         /// <summary>
         /// Adds a middleware type to the application's request pipeline.
@@ -116,7 +116,7 @@ namespace Microsoft.AspNetCore.Builder
             {
                 return async context =>
                 {
-                    var middlewareFactory = (IMiddlewareFactory)context.RequestServices.GetService(typeof(IMiddlewareFactory));
+                    var middlewareFactory = (IMiddlewareFactory?)context.RequestServices.GetService(typeof(IMiddlewareFactory));
                     if (middlewareFactory == null)
                     {
                         // No middleware factory
@@ -198,7 +198,7 @@ namespace Microsoft.AspNetCore.Builder
             }
 
             Expression middlewareInstanceArg = instanceArg;
-            if (methodInfo.DeclaringType != typeof(T))
+            if (methodInfo.DeclaringType != null && methodInfo.DeclaringType != typeof(T))
             {
                 middlewareInstanceArg = Expression.Convert(middlewareInstanceArg, methodInfo.DeclaringType);
             }

+ 1 - 1
src/Http/Http.Abstractions/src/FragmentString.cs

@@ -114,7 +114,7 @@ namespace Microsoft.AspNetCore.Http
             return string.Equals(_value, other._value, StringComparison.Ordinal);
         }
 
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             if (ReferenceEquals(null, obj))
             {

+ 1 - 1
src/Http/Http.Abstractions/src/HostString.cs

@@ -297,7 +297,7 @@ namespace Microsoft.AspNetCore.Http
         /// </summary>
         /// <param name="obj">The <see cref="object"/> to compare against.</param>
         /// <returns><see langword="true" /> if they have the same value.</returns>
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             if (ReferenceEquals(null, obj))
             {

+ 2 - 2
src/Http/Http.Abstractions/src/HttpContext.cs

@@ -47,7 +47,7 @@ namespace Microsoft.AspNetCore.Http
         /// <summary>
         /// Gets or sets a key/value collection that can be used to share data within the scope of this request.
         /// </summary>
-        public abstract IDictionary<object, object> Items { get; set; }
+        public abstract IDictionary<object, object?> Items { get; set; }
 
         /// <summary>
         /// Gets or sets the <see cref="IServiceProvider"/> that provides access to the request's service container.
@@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Http
         /// <summary>
         /// Gets or sets the object used to manage user session data for this request.
         /// </summary>
-        public abstract ISession Session { get; set; }
+        public abstract ISession? Session { get; set; }
 
         /// <summary>
         /// Aborts the connection underlying this request.

+ 1 - 1
src/Http/Http.Abstractions/src/HttpRequest.cs

@@ -131,6 +131,6 @@ namespace Microsoft.AspNetCore.Http
         /// Gets the collection of route values for this request.
         /// </summary>
         /// <returns>The collection of route values for this request.</returns>
-        public virtual RouteValueDictionary RouteValues { get; set; }
+        public virtual RouteValueDictionary RouteValues { get; set; } = null!;
     }
 }

+ 1 - 5
src/Http/Http.Abstractions/src/IMiddlewareFactory.cs

@@ -2,10 +2,6 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace Microsoft.AspNetCore.Http
 {
@@ -19,7 +15,7 @@ namespace Microsoft.AspNetCore.Http
         /// </summary>
         /// <param name="middlewareType">The concrete <see cref="Type"/> of the <see cref="IMiddleware"/>.</param>
         /// <returns>The <see cref="IMiddleware"/> instance.</returns>
-        IMiddleware Create(Type middlewareType);
+        IMiddleware? Create(Type middlewareType);
 
         /// <summary>
         /// Releases a <see cref="IMiddleware"/> instance at the end of each request.

+ 1 - 1
src/Http/Http.Abstractions/src/Internal/HeaderSegment.cs

@@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Http
             return _formatting.Equals(other._formatting) && _data.Equals(other._data);
         }
 
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             if (ReferenceEquals(null, obj))
             {

+ 1 - 1
src/Http/Http.Abstractions/src/Internal/HeaderSegmentCollection.cs

@@ -22,7 +22,7 @@ namespace Microsoft.AspNetCore.Http
             return StringValues.Equals(_headers, other._headers);
         }
 
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             if (ReferenceEquals(null, obj))
             {

+ 2 - 4
src/Http/Http.Abstractions/src/Microsoft.AspNetCore.Http.Abstractions.csproj

@@ -14,18 +14,16 @@ Microsoft.AspNetCore.Http.HttpResponse</Description>
     <PackageTags>aspnetcore</PackageTags>
     <NoWarn>$(NoWarn);CS1591</NoWarn>
     <IsPackable>false</IsPackable>
+    <Nullable>enable</Nullable>
   </PropertyGroup>
 
-  <ItemGroup>
-    <Compile Include="$(SharedSourceRoot)PropertyHelper\**\*.cs" />
-  </ItemGroup>
-
   <ItemGroup>
     <Reference Include="Microsoft.AspNetCore.Http.Features" />
     <Reference Include="Microsoft.Net.Http.Headers" />
 
     <Compile Include="$(SharedSourceRoot)ActivatorUtilities\*.cs" />
     <Compile Include="$(SharedSourceRoot)ParameterDefaultValue\*.cs" />
+    <Compile Include="$(SharedSourceRoot)PropertyHelper\**\*.cs" />
   </ItemGroup>
 
   <ItemGroup>

+ 13 - 13
src/Http/Http.Abstractions/src/PathString.cs

@@ -20,14 +20,14 @@ namespace Microsoft.AspNetCore.Http
         /// </summary>
         public static readonly PathString Empty = new PathString(string.Empty);
 
-        private readonly string _value;
+        private readonly string? _value;
 
         /// <summary>
         /// Initialize the path string with a given value. This value must be in unescaped format. Use
         /// PathString.FromUriComponent(value) if you have a path value which is in an escaped format.
         /// </summary>
         /// <param name="value">The unescaped path to be assigned to the Value property.</param>
-        public PathString(string value)
+        public PathString(string? value)
         {
             if (!string.IsNullOrEmpty(value) && value[0] != '/')
             {
@@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.Http
         /// <summary>
         /// The unescaped path value
         /// </summary>
-        public string Value
+        public string? Value
         {
             get { return _value; }
         }
@@ -72,7 +72,7 @@ namespace Microsoft.AspNetCore.Http
                 return string.Empty;
             }
 
-            var value = _value;
+            var value = _value!;
             var i = 0;
             for (; i < value.Length; i++)
             {
@@ -92,7 +92,7 @@ namespace Microsoft.AspNetCore.Http
 
         private static string ToEscapedUriComponent(string value, int i)
         {
-            StringBuilder buffer = null;
+            StringBuilder? buffer = null;
 
             var start = 0;
             var count = i;
@@ -174,7 +174,7 @@ namespace Microsoft.AspNetCore.Http
                     }
                 }
 
-                return buffer.ToString();
+                return buffer?.ToString() ?? string.Empty;
             }
         }
 
@@ -318,11 +318,11 @@ namespace Microsoft.AspNetCore.Http
         {
             if (HasValue &&
                 other.HasValue &&
-                Value[Value.Length - 1] == '/')
+                Value![Value.Length - 1] == '/')
             {
                 // If the path string has a trailing slash and the other string has a leading slash, we need
                 // to trim one of them.
-                return new PathString(Value + other.Value.Substring(1));
+                return new PathString(Value + other.Value!.Substring(1));
             }
 
             return new PathString(Value + other.Value);
@@ -367,7 +367,7 @@ namespace Microsoft.AspNetCore.Http
         /// </summary>
         /// <param name="obj">The second PathString for comparison.</param>
         /// <returns>True if both PathString values are equal</returns>
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             if (ReferenceEquals(null, obj))
             {
@@ -382,7 +382,7 @@ namespace Microsoft.AspNetCore.Http
         /// <returns>The hash code</returns>
         public override int GetHashCode()
         {
-            return (HasValue ? StringComparer.OrdinalIgnoreCase.GetHashCode(_value) : 0);
+            return (HasValue ? StringComparer.OrdinalIgnoreCase.GetHashCode(_value!) : 0);
         }
 
         /// <summary>
@@ -457,7 +457,7 @@ namespace Microsoft.AspNetCore.Http
         /// Implicitly creates a new PathString from the given string.
         /// </summary>
         /// <param name="s"></param>
-        public static implicit operator PathString(string s)
+        public static implicit operator PathString(string? s)
             => ConvertFromString(s);
 
         /// <summary>
@@ -467,7 +467,7 @@ namespace Microsoft.AspNetCore.Http
         public static implicit operator string(PathString path)
             => path.ToString();
 
-        internal static PathString ConvertFromString(string s)
+        internal static PathString ConvertFromString(string? s)
             => string.IsNullOrEmpty(s) ? new PathString(s) : FromUriComponent(s);
     }
 
@@ -486,7 +486,7 @@ namespace Microsoft.AspNetCore.Http
         public override object ConvertTo(ITypeDescriptorContext context,
            CultureInfo culture, object value, Type destinationType)
             => destinationType == typeof(string) 
-            ? value.ToString() 
+            ? value.ToString() ?? string.Empty
             : base.ConvertTo(context, culture, value, destinationType);
     }
 }

+ 17 - 24
src/Http/Http.Abstractions/src/QueryString.cs

@@ -3,6 +3,7 @@
 
 using System;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Text;
 using System.Text.Encodings.Web;
 using Microsoft.Extensions.Primitives;
@@ -19,37 +20,29 @@ namespace Microsoft.AspNetCore.Http
         /// </summary>
         public static readonly QueryString Empty = new QueryString(string.Empty);
 
-        private readonly string _value;
-
         /// <summary>
         /// Initialize the query string with a given value. This value must be in escaped and delimited format with
         /// a leading '?' character. 
         /// </summary>
         /// <param name="value">The query string to be assigned to the Value property.</param>
-        public QueryString(string value)
+        public QueryString(string? value)
         {
             if (!string.IsNullOrEmpty(value) && value[0] != '?')
             {
                 throw new ArgumentException("The leading '?' must be included for a non-empty query.", nameof(value));
             }
-            _value = value;
+            Value = value;
         }
 
         /// <summary>
         /// The escaped query string with the leading '?' character
         /// </summary>
-        public string Value
-        {
-            get { return _value; }
-        }
+        public string? Value { get; }
 
         /// <summary>
         /// True if the query string is not empty
         /// </summary>
-        public bool HasValue
-        {
-            get { return !string.IsNullOrEmpty(_value); }
-        }
+        public bool HasValue => !string.IsNullOrEmpty(Value);
 
         /// <summary>
         /// Provides the query string escaped in a way which is correct for combining into the URI representation. 
@@ -71,7 +64,7 @@ namespace Microsoft.AspNetCore.Http
         public string ToUriComponent()
         {
             // Escape things properly so System.Uri doesn't mis-interpret the data.
-            return HasValue ? _value.Replace("#", "%23") : string.Empty;
+            return !string.IsNullOrEmpty(Value) ? Value!.Replace("#", "%23") : string.Empty;
         }
 
         /// <summary>
@@ -134,10 +127,10 @@ namespace Microsoft.AspNetCore.Http
         /// </summary>
         /// <param name="parameters"></param>
         /// <returns>The resulting QueryString</returns>
-        public static QueryString Create(IEnumerable<KeyValuePair<string, string>> parameters)
+        public static QueryString Create(IEnumerable<KeyValuePair<string, string?>> parameters)
         {
             var builder = new StringBuilder();
-            bool first = true;
+            var first = true;
             foreach (var pair in parameters)
             {
                 AppendKeyValuePair(builder, pair.Key, pair.Value, first);
@@ -155,7 +148,7 @@ namespace Microsoft.AspNetCore.Http
         public static QueryString Create(IEnumerable<KeyValuePair<string, StringValues>> parameters)
         {
             var builder = new StringBuilder();
-            bool first = true;
+            var first = true;
 
             foreach (var pair in parameters)
             {
@@ -179,17 +172,17 @@ namespace Microsoft.AspNetCore.Http
 
         public QueryString Add(QueryString other)
         {
-            if (!HasValue || Value.Equals("?", StringComparison.Ordinal))
+            if (!HasValue || Value!.Equals("?", StringComparison.Ordinal))
             {
                 return other;
             }
-            if (!other.HasValue || other.Value.Equals("?", StringComparison.Ordinal))
+            if (!other.HasValue || other.Value!.Equals("?", StringComparison.Ordinal))
             {
                 return this;
             }
 
             // ?name1=value1 Add ?name2=value2 returns ?name1=value1&name2=value2
-            return new QueryString(_value + "&" + other.Value.Substring(1));
+            return new QueryString(Value + "&" + other.Value.Substring(1));
         }
 
         public QueryString Add(string name, string value)
@@ -199,7 +192,7 @@ namespace Microsoft.AspNetCore.Http
                 throw new ArgumentNullException(nameof(name));
             }
 
-            if (!HasValue || Value.Equals("?", StringComparison.Ordinal))
+            if (!HasValue || Value!.Equals("?", StringComparison.Ordinal))
             {
                 return Create(name, value);
             }
@@ -215,10 +208,10 @@ namespace Microsoft.AspNetCore.Http
             {
                 return true;
             }
-            return string.Equals(_value, other._value, StringComparison.Ordinal);
+            return string.Equals(Value, other.Value, StringComparison.Ordinal);
         }
 
-        public override bool Equals(object obj)
+        public override bool Equals(object? obj)
         {
             if (ReferenceEquals(null, obj))
             {
@@ -229,7 +222,7 @@ namespace Microsoft.AspNetCore.Http
 
         public override int GetHashCode()
         {
-            return (HasValue ? _value.GetHashCode() : 0);
+            return (HasValue ? Value!.GetHashCode() : 0);
         }
 
         public static bool operator ==(QueryString left, QueryString right)
@@ -247,7 +240,7 @@ namespace Microsoft.AspNetCore.Http
             return left.Add(right);
         }
 
-        private static void AppendKeyValuePair(StringBuilder builder, string key, string value, bool first)
+        private static void AppendKeyValuePair(StringBuilder builder, string key, string? value, bool first)
         {
             builder.Append(first ? "?" : "&");
             builder.Append(UrlEncoder.Default.Encode(key));

+ 2 - 2
src/Http/Http.Abstractions/src/Routing/Endpoint.cs

@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 namespace Microsoft.AspNetCore.Http
@@ -44,6 +44,6 @@ namespace Microsoft.AspNetCore.Http
         /// </summary>
         public RequestDelegate RequestDelegate { get; }
 
-        public override string ToString() => DisplayName ?? base.ToString();
+        public override string? ToString() => DisplayName ?? base.ToString();
     }
 }

+ 3 - 3
src/Http/Http.Abstractions/src/Routing/EndpointHttpContextExtensions.cs

@@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Http
         /// </summary>
         /// <param name="context">The <see cref="HttpContext"/> context.</param>
         /// <returns>The <see cref="Endpoint"/>.</returns>
-        public static Endpoint GetEndpoint(this HttpContext context)
+        public static Endpoint? GetEndpoint(this HttpContext context)
         {
             if (context == null)
             {
@@ -31,7 +31,7 @@ namespace Microsoft.AspNetCore.Http
         /// </summary>
         /// <param name="context">The <see cref="HttpContext"/> context.</param>
         /// <param name="endpoint">The <see cref="Endpoint"/>.</param>
-        public static void SetEndpoint(this HttpContext context, Endpoint endpoint)
+        public static void SetEndpoint(this HttpContext context, Endpoint? endpoint)
         {
             if (context == null)
             {
@@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Http
 
         private class EndpointFeature : IEndpointFeature
         {
-            public Endpoint Endpoint { get; set; }
+            public Endpoint? Endpoint { get; set; }
         }
     }
 }

+ 5 - 5
src/Http/Http.Abstractions/src/Routing/EndpointMetadataCollection.cs

@@ -72,7 +72,7 @@ namespace Microsoft.AspNetCore.Http
         /// The most significant metadata of type <typeparamref name="T"/> or <c>null</c>.
         /// </returns>
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public T GetMetadata<T>() where T : class
+        public T? GetMetadata<T>() where T : class
         {
             if (_cache.TryGetValue(typeof(T), out var obj))
             {
@@ -84,7 +84,7 @@ namespace Microsoft.AspNetCore.Http
             return GetMetadataSlow<T>();
         }
 
-        private T GetMetadataSlow<T>() where T : class
+        private T? GetMetadataSlow<T>() where T : class
         {
             var result = GetOrderedMetadataSlow<T>();
             var length = result.Length;
@@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.Http
         private T[] GetOrderedMetadataSlow<T>() where T : class
         {
             // Perf: avoid allocations totally for the common case where there are no matching metadata.
-            List<T> matches = null;
+            List<T>? matches = null;
 
             var items = _items;
             for (var i = 0; i < items.Length; i++)
@@ -149,7 +149,7 @@ namespace Microsoft.AspNetCore.Http
         /// <summary>
         /// Enumerates the elements of an <see cref="EndpointMetadataCollection"/>.
         /// </summary>
-        public struct Enumerator : IEnumerator<object>
+        public struct Enumerator : IEnumerator<object?>
         {
             // Intentionally not readonly to prevent defensive struct copies
             private object[] _items;
@@ -165,7 +165,7 @@ namespace Microsoft.AspNetCore.Http
             /// <summary>
             /// Gets the element at the current position of the enumerator
             /// </summary>
-            public object Current { get; private set; }
+            public object? Current { get; private set; }
 
             /// <summary>
             /// Releases all resources used by the <see cref="Enumerator"/>.

+ 2 - 2
src/Http/Http.Abstractions/src/Routing/IEndpointFeature.cs

@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 namespace Microsoft.AspNetCore.Http.Features
@@ -13,6 +13,6 @@ namespace Microsoft.AspNetCore.Http.Features
         /// Gets or sets the selected <see cref="Http.Endpoint"/> for the current
         /// request.
         /// </summary>
-        Endpoint Endpoint { get; set; }
+        Endpoint? Endpoint { get; set; }
     }
 }

+ 53 - 46
src/Http/Http.Abstractions/src/Routing/RouteValueDictionary.cs

@@ -6,6 +6,7 @@ using System.Collections;
 using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
 using System.Runtime.CompilerServices;
 using Microsoft.AspNetCore.Http.Abstractions;
 using Microsoft.Extensions.Internal;
@@ -15,13 +16,13 @@ namespace Microsoft.AspNetCore.Routing
     /// <summary>
     /// An <see cref="IDictionary{String, Object}"/> type for route values.
     /// </summary>
-    public class RouteValueDictionary : IDictionary<string, object>, IReadOnlyDictionary<string, object>
+    public class RouteValueDictionary : IDictionary<string, object?>, IReadOnlyDictionary<string, object?>
     {
         // 4 is a good default capacity here because that leaves enough space for area/controller/action/id
         private const int DefaultCapacity = 4;
 
-        internal KeyValuePair<string, object>[] _arrayStorage;
-        internal PropertyStorage _propertyStorage;
+        internal KeyValuePair<string, object?>[] _arrayStorage;
+        internal PropertyStorage? _propertyStorage;
         private int _count;
 
         /// <summary>
@@ -30,7 +31,7 @@ namespace Microsoft.AspNetCore.Routing
         /// </summary>
         /// <param name="items">The items array.</param>
         /// <returns>A new <see cref="RouteValueDictionary"/>.</returns>
-        public static RouteValueDictionary FromArray(KeyValuePair<string, object>[] items)
+        public static RouteValueDictionary FromArray(KeyValuePair<string, object?>[] items)
         {
             if (items == null)
             {
@@ -70,7 +71,7 @@ namespace Microsoft.AspNetCore.Routing
 
             return new RouteValueDictionary()
             {
-                _arrayStorage = items,
+                _arrayStorage = items!,
                 _count = start,
             };
         }
@@ -80,7 +81,7 @@ namespace Microsoft.AspNetCore.Routing
         /// </summary>
         public RouteValueDictionary()
         {
-            _arrayStorage = Array.Empty<KeyValuePair<string, object>>();
+            _arrayStorage = Array.Empty<KeyValuePair<string, object?>>();
         }
 
         /// <summary>
@@ -96,7 +97,7 @@ namespace Microsoft.AspNetCore.Routing
         /// property names are keys, and property values are the values, and copied into the dictionary.
         /// Only public instance non-index properties are considered.
         /// </remarks>
-        public RouteValueDictionary(object values)
+        public RouteValueDictionary(object? values)
         {
             if (values is RouteValueDictionary dictionary)
             {
@@ -105,6 +106,7 @@ namespace Microsoft.AspNetCore.Routing
                     // PropertyStorage is immutable so we can just copy it.
                     _propertyStorage = dictionary._propertyStorage;
                     _count = dictionary._count;
+                    _arrayStorage = Array.Empty<KeyValuePair<string, object?>>();
                     return;
                 }
 
@@ -112,14 +114,14 @@ namespace Microsoft.AspNetCore.Routing
                 if (count > 0)
                 {
                     var other = dictionary._arrayStorage;
-                    var storage = new KeyValuePair<string, object>[count];
+                    var storage = new KeyValuePair<string, object?>[count];
                     Array.Copy(other, 0, storage, 0, count);
                     _arrayStorage = storage;
                     _count = count;
                 }
                 else
                 {
-                    _arrayStorage = Array.Empty<KeyValuePair<string, object>>();
+                    _arrayStorage = Array.Empty<KeyValuePair<string, object?>>();
                 }
 
                 return;
@@ -127,7 +129,7 @@ namespace Microsoft.AspNetCore.Routing
 
             if (values is IEnumerable<KeyValuePair<string, object>> keyValueEnumerable)
             {
-                _arrayStorage = Array.Empty<KeyValuePair<string, object>>();
+                _arrayStorage = Array.Empty<KeyValuePair<string, object?>>();
 
                 foreach (var kvp in keyValueEnumerable)
                 {
@@ -139,7 +141,7 @@ namespace Microsoft.AspNetCore.Routing
 
             if (values is IEnumerable<KeyValuePair<string, string>> stringValueEnumerable)
             {
-                _arrayStorage = Array.Empty<KeyValuePair<string, object>>();
+                _arrayStorage = Array.Empty<KeyValuePair<string, object?>>();
 
                 foreach (var kvp in stringValueEnumerable)
                 {
@@ -154,15 +156,16 @@ namespace Microsoft.AspNetCore.Routing
                 var storage = new PropertyStorage(values);
                 _propertyStorage = storage;
                 _count = storage.Properties.Length;
+                _arrayStorage = Array.Empty<KeyValuePair<string, object?>>();
             }
             else
             {
-                _arrayStorage = Array.Empty<KeyValuePair<string, object>>();
+                _arrayStorage = Array.Empty<KeyValuePair<string, object?>>();
             }
         }
 
         /// <inheritdoc />
-        public object this[string key]
+        public object? this[string key]
         {
             get
             {
@@ -171,8 +174,7 @@ namespace Microsoft.AspNetCore.Routing
                     ThrowArgumentNullExceptionForKey();
                 }
 
-                object value;
-                TryGetValue(key, out value);
+                TryGetValue(key, out var value);
                 return value;
             }
 
@@ -192,11 +194,11 @@ namespace Microsoft.AspNetCore.Routing
                 if (index < 0)
                 {
                     EnsureCapacity(_count + 1);
-                    _arrayStorage[_count++] = new KeyValuePair<string, object>(key, value);
+                    _arrayStorage[_count++] = new KeyValuePair<string, object?>(key, value);
                 }
                 else
                 {
-                    _arrayStorage[index] = new KeyValuePair<string, object>(key, value);
+                    _arrayStorage[index] = new KeyValuePair<string, object?>(key, value);
                 }
             }
         }
@@ -213,7 +215,7 @@ namespace Microsoft.AspNetCore.Routing
         public int Count => _count;
 
         /// <inheritdoc />
-        bool ICollection<KeyValuePair<string, object>>.IsReadOnly => false;
+        bool ICollection<KeyValuePair<string, object?>>.IsReadOnly => false;
 
         /// <inheritdoc />
         public ICollection<string> Keys
@@ -233,17 +235,17 @@ namespace Microsoft.AspNetCore.Routing
             }
         }
 
-        IEnumerable<string> IReadOnlyDictionary<string, object>.Keys => Keys;
+        IEnumerable<string> IReadOnlyDictionary<string, object?>.Keys => Keys;
 
         /// <inheritdoc />
-        public ICollection<object> Values
+        public ICollection<object?> Values
         {
             get
             {
                 EnsureCapacity(_count);
 
                 var array = _arrayStorage;
-                var values = new object[_count];
+                var values = new object?[_count];
                 for (var i = 0; i < values.Length; i++)
                 {
                     values[i] = array[i].Value;
@@ -253,16 +255,16 @@ namespace Microsoft.AspNetCore.Routing
             }
         }
 
-        IEnumerable<object> IReadOnlyDictionary<string, object>.Values => Values;
+        IEnumerable<object?> IReadOnlyDictionary<string, object?>.Values => Values;
 
         /// <inheritdoc />
-        void ICollection<KeyValuePair<string, object>>.Add(KeyValuePair<string, object> item)
+        void ICollection<KeyValuePair<string, object?>>.Add(KeyValuePair<string, object?> item)
         {
             Add(item.Key, item.Value);
         }
 
         /// <inheritdoc />
-        public void Add(string key, object value)
+        public void Add(string key, object? value)
         {
             if (key == null)
             {
@@ -277,7 +279,7 @@ namespace Microsoft.AspNetCore.Routing
                 throw new ArgumentException(message, nameof(key));
             }
 
-            _arrayStorage[_count] = new KeyValuePair<string, object>(key, value);
+            _arrayStorage[_count] = new KeyValuePair<string, object?>(key, value);
             _count++;
         }
 
@@ -291,7 +293,7 @@ namespace Microsoft.AspNetCore.Routing
 
             if (_propertyStorage != null)
             {
-                _arrayStorage = Array.Empty<KeyValuePair<string, object>>();
+                _arrayStorage = Array.Empty<KeyValuePair<string, object?>>();
                 _propertyStorage = null;
                 _count = 0;
                 return;
@@ -302,7 +304,7 @@ namespace Microsoft.AspNetCore.Routing
         }
 
         /// <inheritdoc />
-        bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> item)
+        bool ICollection<KeyValuePair<string, object?>>.Contains(KeyValuePair<string, object?> item)
         {
             return TryGetValue(item.Key, out var value) && EqualityComparer<object>.Default.Equals(value, item.Value);
         }
@@ -330,8 +332,8 @@ namespace Microsoft.AspNetCore.Routing
         }
 
         /// <inheritdoc />
-        void ICollection<KeyValuePair<string, object>>.CopyTo(
-            KeyValuePair<string, object>[] array,
+        void ICollection<KeyValuePair<string, object?>>.CopyTo(
+            KeyValuePair<string, object?>[] array,
             int arrayIndex)
         {
             if (array == null)
@@ -362,7 +364,7 @@ namespace Microsoft.AspNetCore.Routing
         }
 
         /// <inheritdoc />
-        IEnumerator<KeyValuePair<string, object>> IEnumerable<KeyValuePair<string, object>>.GetEnumerator()
+        IEnumerator<KeyValuePair<string, object?>> IEnumerable<KeyValuePair<string, object?>>.GetEnumerator()
         {
             return GetEnumerator();
         }
@@ -374,13 +376,15 @@ namespace Microsoft.AspNetCore.Routing
         }
 
         /// <inheritdoc />
-        bool ICollection<KeyValuePair<string, object>>.Remove(KeyValuePair<string, object> item)
+        bool ICollection<KeyValuePair<string, object?>>.Remove(KeyValuePair<string, object?> item)
         {
             if (Count == 0)
             {
                 return false;
             }
 
+            Debug.Assert(_arrayStorage != null);
+
             EnsureCapacity(Count);
 
             var index = FindIndex(item.Key);
@@ -435,7 +439,7 @@ namespace Microsoft.AspNetCore.Routing
         /// <returns>
         /// <c>true</c> if the object was removed successfully; otherwise, <c>false</c>.
         /// </returns>
-        public bool Remove(string key, out object value)
+        public bool Remove(string key, out object? value)
         {
             if (key == null)
             {
@@ -487,13 +491,13 @@ namespace Microsoft.AspNetCore.Routing
             }
 
             EnsureCapacity(Count + 1);
-            _arrayStorage[Count] = new KeyValuePair<string, object>(key, value);
+            _arrayStorage[Count] = new KeyValuePair<string, object?>(key, value);
             _count++;
             return true;
         }
 
         /// <inheritdoc />
-        public bool TryGetValue(string key, out object value)
+        public bool TryGetValue(string key, out object? value)
         {
             if (key == null)
             {
@@ -508,7 +512,7 @@ namespace Microsoft.AspNetCore.Routing
             return TryGetValueSlow(key, out value);
         }
 
-        private bool TryGetValueSlow(string key, out object value)
+        private bool TryGetValueSlow(string key, [NotNullWhen(true)] out object? value)
         {
             if (_propertyStorage != null)
             {
@@ -527,6 +531,7 @@ namespace Microsoft.AspNetCore.Routing
             return false;
         }
 
+        [DoesNotReturn]
         private static void ThrowArgumentNullExceptionForKey()
         {
             throw new ArgumentNullException("key");
@@ -546,16 +551,16 @@ namespace Microsoft.AspNetCore.Routing
             if (_propertyStorage != null)
             {
                 var storage = _propertyStorage;
-                
+
                 // If we're converting from properties, it's likely due to an 'add' to make sure we have at least
                 // the default amount of space.
                 capacity = Math.Max(DefaultCapacity, Math.Max(storage.Properties.Length, capacity));
-                var array = new KeyValuePair<string, object>[capacity];
+                var array = new KeyValuePair<string, object?>[capacity];
 
                 for (var i = 0; i < storage.Properties.Length; i++)
                 {
                     var property = storage.Properties[i];
-                    array[i] = new KeyValuePair<string, object>(property.Name, property.GetValue(storage.Value));
+                    array[i] = new KeyValuePair<string, object?>(property.Name, property.GetValue(storage.Value));
                 }
 
                 _arrayStorage = array;
@@ -566,7 +571,7 @@ namespace Microsoft.AspNetCore.Routing
             if (_arrayStorage.Length < capacity)
             {
                 capacity = _arrayStorage.Length == 0 ? DefaultCapacity : _arrayStorage.Length * 2;
-                var array = new KeyValuePair<string, object>[capacity];
+                var array = new KeyValuePair<string, object?>[capacity];
                 if (_count > 0)
                 {
                     Array.Copy(_arrayStorage, 0, array, 0, _count);
@@ -596,7 +601,7 @@ namespace Microsoft.AspNetCore.Routing
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        private bool TryFindItem(string key, out object value)
+        private bool TryFindItem(string key, out object? value)
         {
             var array = _arrayStorage;
             var count = _count;
@@ -642,6 +647,8 @@ namespace Microsoft.AspNetCore.Routing
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         private bool ContainsKeyProperties(string key)
         {
+            Debug.Assert(_propertyStorage != null);
+
             var properties = _propertyStorage.Properties;
             for (var i = 0; i < properties.Length; i++)
             {
@@ -654,7 +661,7 @@ namespace Microsoft.AspNetCore.Routing
             return false;
         }
 
-        public struct Enumerator : IEnumerator<KeyValuePair<string, object>>
+        public struct Enumerator : IEnumerator<KeyValuePair<string, object?>>
         {
             private readonly RouteValueDictionary _dictionary;
             private int _index;
@@ -672,7 +679,7 @@ namespace Microsoft.AspNetCore.Routing
                 _index = 0;
             }
 
-            public KeyValuePair<string, object> Current { get; private set; }
+            public KeyValuePair<string, object?> Current { get; private set; }
 
             object IEnumerator.Current => Current;
 
@@ -699,12 +706,12 @@ namespace Microsoft.AspNetCore.Routing
 
             private bool MoveNextRare()
             {
-                var dictionary = _dictionary; 
+                var dictionary = _dictionary;
                 if (dictionary._propertyStorage != null && ((uint)_index < (uint)dictionary._count))
                 {
                     var storage = dictionary._propertyStorage;
                     var property = storage.Properties[_index];
-                    Current = new KeyValuePair<string, object>(property.Name, property.GetValue(storage.Value));
+                    Current = new KeyValuePair<string, object?>(property.Name, property.GetValue(storage.Value));
                     _index++;
                     return true;
                 }
@@ -735,7 +742,7 @@ namespace Microsoft.AspNetCore.Routing
 
                 // Cache the properties so we can know if we've already validated them for duplicates.
                 var type = Value.GetType();
-                if (!_propertyCache.TryGetValue(type, out Properties))
+                if (!_propertyCache.TryGetValue(type, out Properties!))
                 {
                     Properties = PropertyHelper.GetVisibleProperties(type);
                     ValidatePropertyNames(type, Properties);
@@ -765,4 +772,4 @@ namespace Microsoft.AspNetCore.Routing
             }
         }
     }
-}
+}

+ 1 - 1
src/Http/Http.Abstractions/src/WebSocketManager.cs

@@ -36,6 +36,6 @@ namespace Microsoft.AspNetCore.Http
         /// </summary>
         /// <param name="subProtocol">The sub-protocol to use.</param>
         /// <returns>A task representing the completion of the transition.</returns>
-        public abstract Task<WebSocket> AcceptWebSocketAsync(string subProtocol);
+        public abstract Task<WebSocket> AcceptWebSocketAsync(string? subProtocol);
     }
 }

+ 1 - 1
src/Http/Http.Abstractions/test/EndpointHttpContextExtensionsTests.cs

@@ -149,7 +149,7 @@ namespace Microsoft.AspNetCore.Http.Abstractions.Tests
 
         private class EndpointFeature : IEndpointFeature
         {
-            public Endpoint Endpoint { get; set; }
+            public Endpoint? Endpoint { get; set; }
         }
     }
 }

+ 5 - 5
src/Http/Http.Abstractions/test/MapPathMiddlewareTests.cs

@@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Builder.Extensions
             context.Response.StatusCode = 200;
             context.Items["test.PathBase"] = context.Request.PathBase.Value;
             context.Items["test.Path"] = context.Request.Path.Value;
-            return Task.FromResult<object>(null);
+            return Task.FromResult<object?>(null);
         }
 
         private static void UseSuccess(IApplicationBuilder app)
@@ -42,8 +42,8 @@ namespace Microsoft.AspNetCore.Builder.Extensions
             var builder = new ApplicationBuilder(serviceProvider: null);
             var noMiddleware = new ApplicationBuilder(serviceProvider: null).Build();
             var noOptions = new MapOptions();
-            Assert.Throws<ArgumentNullException>(() => builder.Map("/foo", configuration: null));
-            Assert.Throws<ArgumentNullException>(() => new MapMiddleware(noMiddleware, null));
+            Assert.Throws<ArgumentNullException>(() => builder.Map("/foo", configuration: null!));
+            Assert.Throws<ArgumentNullException>(() => new MapMiddleware(noMiddleware, null!));
         }
 
         [Theory]
@@ -91,7 +91,7 @@ namespace Microsoft.AspNetCore.Builder.Extensions
             await app.Invoke(context);
 
             Assert.Equal(200, context.Response.StatusCode);
-            Assert.Equal(basePath + requestPath.Substring(0, matchPath.Length), (string)context.Items["test.PathBase"]);
+            Assert.Equal(basePath + requestPath.Substring(0, matchPath.Length), (string)context.Items["test.PathBase"]!);
             Assert.Equal(requestPath.Substring(matchPath.Length), context.Items["test.Path"]);
         }
 
@@ -119,7 +119,7 @@ namespace Microsoft.AspNetCore.Builder.Extensions
             await app.Invoke(context);
 
             Assert.Equal(200, context.Response.StatusCode);
-            Assert.Equal(basePath, (string)context.Items["test.PathBase"]);
+            Assert.Equal(basePath, (string)context.Items["test.PathBase"]!);
             Assert.Equal(requestPath, context.Items["test.Path"]);
         }
 

+ 7 - 8
src/Http/Http.Abstractions/test/MapPredicateMiddlewareTests.cs

@@ -3,7 +3,6 @@
 
 using System;
 using System.Threading.Tasks;
-using Microsoft.AspNetCore.Builder.Internal;
 using Microsoft.AspNetCore.Http;
 using Xunit;
 
@@ -18,7 +17,7 @@ namespace Microsoft.AspNetCore.Builder.Extensions
         private static Task Success(HttpContext context)
         {
             context.Response.StatusCode = 200;
-            return Task.FromResult<object>(null);
+            return Task.FromResult<object>(null!);
         }
 
         private static void UseSuccess(IApplicationBuilder app)
@@ -52,12 +51,12 @@ namespace Microsoft.AspNetCore.Builder.Extensions
             var builder = new ApplicationBuilder(serviceProvider: null);
             var noMiddleware = new ApplicationBuilder(serviceProvider: null).Build();
             var noOptions = new MapWhenOptions();
-            Assert.Throws<ArgumentNullException>(() => builder.MapWhen(null, UseNotImplemented));
-            Assert.Throws<ArgumentNullException>(() => builder.MapWhen(NotImplementedPredicate, configuration: null));
-            Assert.Throws<ArgumentNullException>(() => new MapWhenMiddleware(null, noOptions));
-            Assert.Throws<ArgumentNullException>(() => new MapWhenMiddleware(noMiddleware, null));
-            Assert.Throws<ArgumentNullException>(() => new MapWhenMiddleware(null, noOptions));
-            Assert.Throws<ArgumentNullException>(() => new MapWhenMiddleware(noMiddleware, null));
+            Assert.Throws<ArgumentNullException>(() => builder.MapWhen(null!, UseNotImplemented));
+            Assert.Throws<ArgumentNullException>(() => builder.MapWhen(NotImplementedPredicate, configuration: null!));
+            Assert.Throws<ArgumentNullException>(() => new MapWhenMiddleware(null!, noOptions));
+            Assert.Throws<ArgumentNullException>(() => new MapWhenMiddleware(noMiddleware, null!));
+            Assert.Throws<ArgumentNullException>(() => new MapWhenMiddleware(null!, noOptions));
+            Assert.Throws<ArgumentNullException>(() => new MapWhenMiddleware(noMiddleware, null!));
         }
 
         [Fact]

+ 1 - 0
src/Http/Http.Abstractions/test/Microsoft.AspNetCore.Http.Abstractions.Tests.csproj

@@ -2,6 +2,7 @@
 
   <PropertyGroup>
     <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
+    <Nullable>enable</Nullable>
   </PropertyGroup>
 
   <ItemGroup>

+ 5 - 5
src/Http/Http.Abstractions/test/QueryStringTests.cs

@@ -70,11 +70,11 @@ namespace Microsoft.AspNetCore.Http.Abstractions
         {
             var query = QueryString.Create(new[]
             {
-                new KeyValuePair<string, string>("key1", "value1"),
-                new KeyValuePair<string, string>("key2", "value2"),
-                new KeyValuePair<string, string>("key3", "value3"),
-                new KeyValuePair<string, string>("key4", null),
-                new KeyValuePair<string, string>("key5", "")
+                new KeyValuePair<string, string?>("key1", "value1"),
+                new KeyValuePair<string, string?>("key2", "value2"),
+                new KeyValuePair<string, string?>("key3", "value3"),
+                new KeyValuePair<string, string?>("key4", null),
+                new KeyValuePair<string, string?>("key5", "")
             });
             Assert.Equal("?key1=value1&key2=value2&key3=value3&key4=&key5=", query.Value);
         }

Plik diff jest za duży
+ 140 - 147
src/Http/Http.Abstractions/test/RouteValueDictionaryTests.cs


+ 7 - 7
src/Http/Http.Abstractions/test/UseMiddlewareTest.cs

@@ -244,10 +244,10 @@ namespace Microsoft.AspNetCore.Http
 
         public class BasicMiddlewareFactory : IMiddlewareFactory
         {
-            public IMiddleware Created { get; private set; }
-            public IMiddleware Released { get; private set; }
+            public IMiddleware? Created { get; private set; }
+            public IMiddleware? Released { get; private set; }
 
-            public IMiddleware Create(Type middlewareType)
+            public IMiddleware? Create(Type middlewareType)
             {
                 Created = Activator.CreateInstance(middlewareType) as IMiddleware;
                 return Created;
@@ -261,7 +261,7 @@ namespace Microsoft.AspNetCore.Http
 
         public class BadMiddlewareFactory : IMiddlewareFactory
         {
-            public IMiddleware Create(Type middlewareType) => null;
+            public IMiddleware? Create(Type middlewareType) => null;
 
             public void Release(IMiddleware middleware) { }
         }
@@ -272,14 +272,14 @@ namespace Microsoft.AspNetCore.Http
 
             public void AddService(Type type, object value) => _services[type] = value;
 
-            public object GetService(Type serviceType)
+            public object? GetService(Type serviceType)
             {
                 if (serviceType == typeof(IServiceProvider))
                 {
                     return this;
                 }
 
-                if (_services.TryGetValue(serviceType, out object value))
+                if (_services.TryGetValue(serviceType, out var value))
                 {
                     return value;
                 }
@@ -291,7 +291,7 @@ namespace Microsoft.AspNetCore.Http
         {
             public MiddlewareInjectWithOutAndRefParams(RequestDelegate next) { }
 
-            public Task Invoke(HttpContext context, ref IServiceProvider sp1, out IServiceProvider sp2)
+            public Task Invoke(HttpContext context, ref IServiceProvider? sp1, out IServiceProvider? sp2)
             {
                 sp1 = null;
                 sp2 = null;

+ 3 - 2
src/Http/Http.Abstractions/test/UsePathBaseExtensionsTests.cs

@@ -145,8 +145,9 @@ namespace Microsoft.AspNetCore.Builder.Extensions
             await builder.Build().Invoke(requestContext);
 
             // Assert path and pathBase are split after middleware
-            Assert.Equal(expectedPath, ((PathString)requestContext.Items["test.Path"]).Value);
-            Assert.Equal(expectedPathBase, ((PathString)requestContext.Items["test.PathBase"]).Value);
+            Assert.Equal(expectedPath, ((PathString?)requestContext.Items["test.Path"])!.Value.Value);
+            Assert.Equal(expectedPathBase, ((PathString?)requestContext.Items["test.PathBase"])!.Value.Value);
+
             // Assert path and pathBase are reset after request
             Assert.Equal(pathBase, requestContext.Request.PathBase.Value);
             Assert.Equal(requestPath, requestContext.Request.Path.Value);

+ 3 - 3
src/Http/Http.Abstractions/test/UseWhenExtensionsTests.cs

@@ -18,8 +18,8 @@ namespace Microsoft.AspNetCore.Builder.Extensions
             var builder = CreateBuilder();
 
             // Act
-            Action nullPredicate = () => builder.UseWhen(null, app => { });
-            Action nullConfiguration = () => builder.UseWhen(TruePredicate, null);
+            Action nullPredicate = () => builder.UseWhen(null!, app => { });
+            Action nullConfiguration = () => builder.UseWhen(TruePredicate, null!);
 
             // Assert
             Assert.Throws<ArgumentNullException>(nullPredicate);
@@ -146,7 +146,7 @@ namespace Microsoft.AspNetCore.Builder.Extensions
                     }
                 }
 
-                return terminate ? Task.FromResult<object>(null) : next();
+                return terminate ? Task.FromResult<object?>(null) : next();
             };
         }
 

+ 1 - 0
src/Http/Http.Features/ref/Microsoft.AspNetCore.Http.Features.csproj

@@ -3,6 +3,7 @@
   <PropertyGroup>
     <TargetFrameworks>netstandard2.0;$(DefaultNetCoreTargetFramework)</TargetFrameworks>
     <TargetFrameworks Condition="'$(DotNetBuildFromSource)' == 'true'">$(DefaultNetCoreTargetFramework)</TargetFrameworks>
+    <Nullable>annotations</Nullable>
   </PropertyGroup>
   <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
     <Compile Include="Microsoft.AspNetCore.Http.Features.netstandard2.0.cs" />

+ 11 - 7
src/Http/Http.Features/ref/Microsoft.AspNetCore.Http.Features.netcoreapp.cs

@@ -6,12 +6,12 @@ namespace Microsoft.AspNetCore.Http
     public partial class CookieOptions
     {
         public CookieOptions() { }
-        public string Domain { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
+        public string? Domain { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public System.DateTimeOffset? Expires { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public bool HttpOnly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public bool IsEssential { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public System.TimeSpan? MaxAge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
-        public string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
+        public string? Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public Microsoft.AspNetCore.Http.SameSiteMode SameSite { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public bool Secure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
     }
@@ -92,7 +92,7 @@ namespace Microsoft.AspNetCore.Http
     public partial class WebSocketAcceptContext
     {
         public WebSocketAcceptContext() { }
-        public virtual string SubProtocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
+        public virtual string? SubProtocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
     }
 }
 namespace Microsoft.AspNetCore.Http.Features
@@ -102,9 +102,10 @@ namespace Microsoft.AspNetCore.Http.Features
         public FeatureCollection() { }
         public FeatureCollection(Microsoft.AspNetCore.Http.Features.IFeatureCollection defaults) { }
         public bool IsReadOnly { get { throw null; } }
-        public object this[System.Type key] { get { throw null; } set { } }
+        public object? this[System.Type key] { get { throw null; } set { } }
         public virtual int Revision { get { throw null; } }
         public System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<System.Type, object>> GetEnumerator() { throw null; }
+        [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute]
         public TFeature Get<TFeature>() { throw null; }
         public void Set<TFeature>(TFeature instance) { }
         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
@@ -114,12 +115,14 @@ namespace Microsoft.AspNetCore.Http.Features
     {
         private object _dummy;
         private int _dummyPrimitive;
+        [System.Diagnostics.CodeAnalysis.AllowNullAttribute]
+        [System.Diagnostics.CodeAnalysis.MaybeNullAttribute]
         public TCache Cache;
         public FeatureReferences(Microsoft.AspNetCore.Http.Features.IFeatureCollection collection) { throw null; }
         public Microsoft.AspNetCore.Http.Features.IFeatureCollection Collection { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
         public int Revision { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
-        public TFeature Fetch<TFeature>(ref TFeature cached, System.Func<Microsoft.AspNetCore.Http.Features.IFeatureCollection, TFeature> factory) where TFeature : class { throw null; }
-        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public TFeature Fetch<TFeature, TState>(ref TFeature cached, TState state, System.Func<TState, TFeature> factory) where TFeature : class { throw null; }
+        public TFeature Fetch<TFeature>([System.Diagnostics.CodeAnalysis.AllowNullAttribute, System.Diagnostics.CodeAnalysis.MaybeNullAttribute] ref TFeature cached, System.Func<Microsoft.AspNetCore.Http.Features.IFeatureCollection, TFeature> factory) where TFeature : class { throw null; }
+        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public TFeature Fetch<TFeature, TState>([System.Diagnostics.CodeAnalysis.AllowNullAttribute, System.Diagnostics.CodeAnalysis.MaybeNullAttribute] ref TFeature cached, TState state, System.Func<TState, TFeature> factory) where TFeature : class { throw null; }
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public void Initalize(Microsoft.AspNetCore.Http.Features.IFeatureCollection collection) { }
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]public void Initalize(Microsoft.AspNetCore.Http.Features.IFeatureCollection collection, int revision) { }
     }
@@ -129,6 +132,7 @@ namespace Microsoft.AspNetCore.Http.Features
         private T _feature;
         private int _dummyPrimitive;
         public static readonly Microsoft.AspNetCore.Http.Features.FeatureReference<T> Default;
+        [return: System.Diagnostics.CodeAnalysis.MaybeNullAttribute]
         public T Fetch(Microsoft.AspNetCore.Http.Features.IFeatureCollection features) { throw null; }
         public T Update(Microsoft.AspNetCore.Http.Features.IFeatureCollection features, T feature) { throw null; }
     }
@@ -141,7 +145,7 @@ namespace Microsoft.AspNetCore.Http.Features
     public partial interface IFeatureCollection : System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<System.Type, object>>, System.Collections.IEnumerable
     {
         bool IsReadOnly { get; }
-        object this[System.Type key] { get; set; }
+        object? this[System.Type key] { get; set; }
         int Revision { get; }
         TFeature Get<TFeature>();
         void Set<TFeature>(TFeature instance);

+ 5 - 5
src/Http/Http.Features/ref/Microsoft.AspNetCore.Http.Features.netstandard2.0.cs

@@ -6,12 +6,12 @@ namespace Microsoft.AspNetCore.Http
     public partial class CookieOptions
     {
         public CookieOptions() { }
-        public string Domain { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
+        public string? Domain { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public System.DateTimeOffset? Expires { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public bool HttpOnly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public bool IsEssential { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public System.TimeSpan? MaxAge { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
-        public string Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
+        public string? Path { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public Microsoft.AspNetCore.Http.SameSiteMode SameSite { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public bool Secure { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
     }
@@ -92,7 +92,7 @@ namespace Microsoft.AspNetCore.Http
     public partial class WebSocketAcceptContext
     {
         public WebSocketAcceptContext() { }
-        public virtual string SubProtocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
+        public virtual string? SubProtocol { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
     }
 }
 namespace Microsoft.AspNetCore.Http.Features
@@ -102,7 +102,7 @@ namespace Microsoft.AspNetCore.Http.Features
         public FeatureCollection() { }
         public FeatureCollection(Microsoft.AspNetCore.Http.Features.IFeatureCollection defaults) { }
         public bool IsReadOnly { get { throw null; } }
-        public object this[System.Type key] { get { throw null; } set { } }
+        public object? this[System.Type key] { get { throw null; } set { } }
         public virtual int Revision { get { throw null; } }
         public System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<System.Type, object>> GetEnumerator() { throw null; }
         public TFeature Get<TFeature>() { throw null; }
@@ -141,7 +141,7 @@ namespace Microsoft.AspNetCore.Http.Features
     public partial interface IFeatureCollection : System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<System.Type, object>>, System.Collections.IEnumerable
     {
         bool IsReadOnly { get; }
-        object this[System.Type key] { get; set; }
+        object? this[System.Type key] { get; set; }
         int Revision { get; }
         TFeature Get<TFeature>();
         void Set<TFeature>(TFeature instance);

+ 2 - 2
src/Http/Http.Features/src/CookieOptions.cs

@@ -22,13 +22,13 @@ namespace Microsoft.AspNetCore.Http
         /// Gets or sets the domain to associate the cookie with.
         /// </summary>
         /// <returns>The domain to associate the cookie with.</returns>
-        public string Domain { get; set; }
+        public string? Domain { get; set; }
 
         /// <summary>
         /// Gets or sets the cookie path.
         /// </summary>
         /// <returns>The cookie path.</returns>
-        public string Path { get; set; }
+        public string? Path { get; set; }
 
         /// <summary>
         /// Gets or sets the expiration date and time for the cookie.

+ 7 - 5
src/Http/Http.Features/src/FeatureCollection.cs

@@ -4,6 +4,7 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
 using System.Linq;
 
 namespace Microsoft.AspNetCore.Http.Features
@@ -11,8 +12,8 @@ namespace Microsoft.AspNetCore.Http.Features
     public class FeatureCollection : IFeatureCollection
     {
         private static KeyComparer FeatureKeyComparer = new KeyComparer();
-        private readonly IFeatureCollection _defaults;
-        private IDictionary<Type, object> _features;
+        private readonly IFeatureCollection? _defaults;
+        private IDictionary<Type, object>? _features;
         private volatile int _containerRevision;
 
         public FeatureCollection()
@@ -31,7 +32,7 @@ namespace Microsoft.AspNetCore.Http.Features
 
         public bool IsReadOnly { get { return false; } }
 
-        public object this[Type key]
+        public object? this[Type key]
         {
             get
             {
@@ -40,7 +41,7 @@ namespace Microsoft.AspNetCore.Http.Features
                     throw new ArgumentNullException(nameof(key));
                 }
 
-                object result;
+                object? result;
                 return _features != null && _features.TryGetValue(key, out result) ? result : _defaults?[key];
             }
             set
@@ -93,6 +94,7 @@ namespace Microsoft.AspNetCore.Http.Features
             }
         }
 
+        [return: MaybeNull]
         public TFeature Get<TFeature>()
         {
             return (TFeature)this[typeof(TFeature)];
@@ -116,4 +118,4 @@ namespace Microsoft.AspNetCore.Http.Features
             }
         }
     }
-}
+}

+ 6 - 3
src/Http/Http.Features/src/FeatureReference.cs

@@ -1,6 +1,8 @@
 // Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
+using System.Diagnostics.CodeAnalysis;
+
 namespace Microsoft.AspNetCore.Http.Features
 {
     public struct FeatureReference<T>
@@ -14,15 +16,16 @@ namespace Microsoft.AspNetCore.Http.Features
             _revision = revision;
         }
 
-        public static readonly FeatureReference<T> Default = new FeatureReference<T>(default(T), -1);
+        public static readonly FeatureReference<T> Default = new FeatureReference<T>(default(T)!, -1);
 
+        [return: MaybeNull]
         public T Fetch(IFeatureCollection features)
         {
             if (_revision == features.Revision)
             {
                 return _feature;
             }
-            _feature = (T)features[typeof(T)];
+            _feature = (T)features[typeof(T)]!;
             _revision = features.Revision;
             return _feature;
         }
@@ -35,4 +38,4 @@ namespace Microsoft.AspNetCore.Http.Features
             return feature;
         }
     }
-}
+}

+ 7 - 5
src/Http/Http.Features/src/FeatureReferences.cs

@@ -2,6 +2,7 @@
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using System;
+using System.Diagnostics.CodeAnalysis;
 using System.Runtime.CompilerServices;
 
 namespace Microsoft.AspNetCore.Http.Features
@@ -36,6 +37,7 @@ namespace Microsoft.AspNetCore.Http.Features
         // be able to pass ref values that "dot through" the TCache struct memory, 
         // if it was a Property then that getter would return a copy of the memory
         // preventing the use of "ref"
+        [AllowNull, MaybeNull]
         public TCache Cache;
 
         // Careful with modifications to the Fetch method; it is carefully constructed for inlining
@@ -60,7 +62,7 @@ namespace Microsoft.AspNetCore.Http.Features
         // Generally Fetch is called at a ratio > x4 of UpdateCached so this is a large gain
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         public TFeature Fetch<TFeature, TState>(
-            ref TFeature cached,
+            [AllowNull, MaybeNull]ref TFeature cached,
             TState state,
             Func<TState, TFeature> factory) where TFeature : class
         {
@@ -69,12 +71,12 @@ namespace Microsoft.AspNetCore.Http.Features
             if (Revision != revision)
             {
                 // Clear cached value to force call to UpdateCached
-                cached = null;
+                cached = null!;
                 // Collection changed, clear whole feature cache
                 flush = true;
             }
 
-            return cached ?? UpdateCached(ref cached, state, factory, revision, flush);
+            return cached ?? UpdateCached(ref cached!, state, factory, revision, flush);
         }
 
         // Update and cache clearing logic, when the fast-path in Fetch isn't applicable
@@ -106,8 +108,8 @@ namespace Microsoft.AspNetCore.Http.Features
             return cached;
         }
 
-        public TFeature Fetch<TFeature>(ref TFeature cached, Func<IFeatureCollection, TFeature> factory)
-            where TFeature : class => Fetch(ref cached, Collection, factory);
+        public TFeature Fetch<TFeature>([AllowNull, MaybeNull]ref TFeature cached, Func<IFeatureCollection, TFeature> factory)
+            where TFeature : class => Fetch(ref cached!, Collection, factory);
 
         private static int ContextDisposed()
         {

+ 1 - 1
src/Http/Http.Features/src/IFeatureCollection.cs

@@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Http.Features
         /// </summary>
         /// <param name="key"></param>
         /// <returns>The requested feature, or null if it is not present.</returns>
-        object this[Type key] { get; set; }
+        object? this[Type key] { get; set; }
 
         /// <summary>
         /// Retrieves the requested feature from the collection.

+ 3 - 1
src/Http/Http.Features/src/Microsoft.AspNetCore.Http.Features.csproj

@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
     <Description>ASP.NET Core HTTP feature interface definitions.</Description>
@@ -8,8 +8,10 @@
     <NoWarn>$(NoWarn);CS1591</NoWarn>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <PackageTags>aspnetcore</PackageTags>
+    <Nullable>enable</Nullable>
   </PropertyGroup>
 
+
   <ItemGroup>
     <Reference Include="Microsoft.Extensions.Primitives" />
     <Reference Include="System.IO.Pipelines" />

+ 2 - 2
src/Http/Http.Features/src/WebSocketAcceptContext.cs

@@ -5,6 +5,6 @@ namespace Microsoft.AspNetCore.Http
 {
     public class WebSocketAcceptContext
     {
-        public virtual string SubProtocol { get; set; }
+        public virtual string? SubProtocol { get; set; }
     }
-}
+}

+ 2 - 2
src/Http/Http.Features/test/FeatureCollectionTests.cs

@@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Http.Features
 
             interfaces[typeof(IThing)] = thing;
 
-            object thing2 = interfaces[typeof(IThing)];
+            var thing2 = interfaces[typeof(IThing)];
             Assert.Equal(thing2, thing);
         }
 
@@ -41,7 +41,7 @@ namespace Microsoft.AspNetCore.Http.Features
 
             interfaces[typeof(IThing)] = null;
 
-            object thing2 = interfaces[typeof(IThing)];
+            var thing2 = interfaces[typeof(IThing)];
             Assert.Null(thing2);
         }
     }

+ 1 - 0
src/Http/Http.Features/test/Microsoft.AspNetCore.Http.Features.Tests.csproj

@@ -2,6 +2,7 @@
 
   <PropertyGroup>
     <TargetFramework>$(DefaultNetCoreTargetFramework)</TargetFramework>
+    <Nullable>enable</Nullable>
   </PropertyGroup>
 
   <ItemGroup>

+ 4 - 4
src/Http/Http/ref/Microsoft.AspNetCore.Http.netcoreapp.cs

@@ -64,7 +64,7 @@ namespace Microsoft.AspNetCore.Http
         public System.Collections.Generic.ICollection<string> Keys { get { throw null; } }
         public bool ContainsKey(string key) { throw null; }
         public Microsoft.AspNetCore.Http.FormCollection.Enumerator GetEnumerator() { throw null; }
-        System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>> System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<System.String,Microsoft.Extensions.Primitives.StringValues>>.GetEnumerator() { throw null; }
+        System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>> System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>>.GetEnumerator() { throw null; }
         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
         public bool TryGetValue(string key, out Microsoft.Extensions.Primitives.StringValues value) { throw null; }
         [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
@@ -110,7 +110,7 @@ namespace Microsoft.AspNetCore.Http
         public bool IsReadOnly { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public Microsoft.Extensions.Primitives.StringValues this[string key] { get { throw null; } set { } }
         public System.Collections.Generic.ICollection<string> Keys { get { throw null; } }
-        Microsoft.Extensions.Primitives.StringValues System.Collections.Generic.IDictionary<System.String,Microsoft.Extensions.Primitives.StringValues>.this[string key] { get { throw null; } set { } }
+        Microsoft.Extensions.Primitives.StringValues System.Collections.Generic.IDictionary<string, Microsoft.Extensions.Primitives.StringValues>.this[string key] { get { throw null; } set { } }
         public System.Collections.Generic.ICollection<Microsoft.Extensions.Primitives.StringValues> Values { get { throw null; } }
         public void Add(System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues> item) { }
         public void Add(string key, Microsoft.Extensions.Primitives.StringValues value) { }
@@ -121,7 +121,7 @@ namespace Microsoft.AspNetCore.Http
         public Microsoft.AspNetCore.Http.HeaderDictionary.Enumerator GetEnumerator() { throw null; }
         public bool Remove(System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues> item) { throw null; }
         public bool Remove(string key) { throw null; }
-        System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>> System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<System.String,Microsoft.Extensions.Primitives.StringValues>>.GetEnumerator() { throw null; }
+        System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>> System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>>.GetEnumerator() { throw null; }
         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
         public bool TryGetValue(string key, out Microsoft.Extensions.Primitives.StringValues value) { throw null; }
         [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
@@ -176,7 +176,7 @@ namespace Microsoft.AspNetCore.Http
         public System.Collections.Generic.ICollection<string> Keys { get { throw null; } }
         public bool ContainsKey(string key) { throw null; }
         public Microsoft.AspNetCore.Http.QueryCollection.Enumerator GetEnumerator() { throw null; }
-        System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>> System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<System.String,Microsoft.Extensions.Primitives.StringValues>>.GetEnumerator() { throw null; }
+        System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>> System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>>.GetEnumerator() { throw null; }
         System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
         public bool TryGetValue(string key, out Microsoft.Extensions.Primitives.StringValues value) { throw null; }
         [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]

+ 17 - 0
src/Http/HttpAbstractions.sln

@@ -117,6 +117,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Author
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Cors", "..\Middleware\CORS\src\Microsoft.AspNetCore.Cors.csproj", "{09168958-FD5B-4D25-8FBF-75E2C80D903B}"
 EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Metadata", "Metadata", "{B1C66DEF-EBEE-4F3C-A5F5-65FA9964AC67}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Metadata", "Metadata\src\Microsoft.AspNetCore.Metadata.csproj", "{CAAB06B8-0E70-49FE-92A5-46A35A089481}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -631,6 +635,18 @@ Global
 		{09168958-FD5B-4D25-8FBF-75E2C80D903B}.Release|x64.Build.0 = Release|Any CPU
 		{09168958-FD5B-4D25-8FBF-75E2C80D903B}.Release|x86.ActiveCfg = Release|Any CPU
 		{09168958-FD5B-4D25-8FBF-75E2C80D903B}.Release|x86.Build.0 = Release|Any CPU
+		{CAAB06B8-0E70-49FE-92A5-46A35A089481}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{CAAB06B8-0E70-49FE-92A5-46A35A089481}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{CAAB06B8-0E70-49FE-92A5-46A35A089481}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{CAAB06B8-0E70-49FE-92A5-46A35A089481}.Debug|x64.Build.0 = Debug|Any CPU
+		{CAAB06B8-0E70-49FE-92A5-46A35A089481}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{CAAB06B8-0E70-49FE-92A5-46A35A089481}.Debug|x86.Build.0 = Debug|Any CPU
+		{CAAB06B8-0E70-49FE-92A5-46A35A089481}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{CAAB06B8-0E70-49FE-92A5-46A35A089481}.Release|Any CPU.Build.0 = Release|Any CPU
+		{CAAB06B8-0E70-49FE-92A5-46A35A089481}.Release|x64.ActiveCfg = Release|Any CPU
+		{CAAB06B8-0E70-49FE-92A5-46A35A089481}.Release|x64.Build.0 = Release|Any CPU
+		{CAAB06B8-0E70-49FE-92A5-46A35A089481}.Release|x86.ActiveCfg = Release|Any CPU
+		{CAAB06B8-0E70-49FE-92A5-46A35A089481}.Release|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -681,6 +697,7 @@ Global
 		{21AC56E7-4E77-4B0E-B63E-C8E836E4D14E} = {80A090C8-ED02-4DE3-875A-30DCCDBD84BA}
 		{8BCAA9EC-0ACD-435C-BF8A-8C843499FF7B} = {793FFE24-138A-4C3D-81AB-18D625E36230}
 		{09168958-FD5B-4D25-8FBF-75E2C80D903B} = {793FFE24-138A-4C3D-81AB-18D625E36230}
+		{CAAB06B8-0E70-49FE-92A5-46A35A089481} = {B1C66DEF-EBEE-4F3C-A5F5-65FA9964AC67}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {85B5E151-2E9D-419C-83DD-0DDCF446C83A}

+ 1 - 0
src/Http/Metadata/ref/Microsoft.AspNetCore.Metadata.csproj

@@ -3,6 +3,7 @@
   <PropertyGroup>
     <TargetFrameworks>netstandard2.0;$(DefaultNetCoreTargetFramework)</TargetFrameworks>
     <TargetFrameworks Condition="'$(DotNetBuildFromSource)' == 'true'">$(DefaultNetCoreTargetFramework)</TargetFrameworks>
+    <Nullable>annotations</Nullable>
   </PropertyGroup>
   <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
     <Compile Include="Microsoft.AspNetCore.Metadata.netstandard2.0.cs" />

+ 3 - 3
src/Http/Metadata/ref/Microsoft.AspNetCore.Metadata.netcoreapp.cs

@@ -8,8 +8,8 @@ namespace Microsoft.AspNetCore.Authorization
     }
     public partial interface IAuthorizeData
     {
-        string AuthenticationSchemes { get; set; }
-        string Policy { get; set; }
-        string Roles { get; set; }
+        string? AuthenticationSchemes { get; set; }
+        string? Policy { get; set; }
+        string? Roles { get; set; }
     }
 }

+ 3 - 3
src/Http/Metadata/ref/Microsoft.AspNetCore.Metadata.netstandard2.0.cs

@@ -8,8 +8,8 @@ namespace Microsoft.AspNetCore.Authorization
     }
     public partial interface IAuthorizeData
     {
-        string AuthenticationSchemes { get; set; }
-        string Policy { get; set; }
-        string Roles { get; set; }
+        string? AuthenticationSchemes { get; set; }
+        string? Policy { get; set; }
+        string? Roles { get; set; }
     }
 }

+ 3 - 3
src/Http/Metadata/src/IAuthorizeData.cs

@@ -11,16 +11,16 @@ namespace Microsoft.AspNetCore.Authorization
         /// <summary>
         /// Gets or sets the policy name that determines access to the resource.
         /// </summary>
-        string Policy { get; set; }
+        string? Policy { get; set; }
 
         /// <summary>
         /// Gets or sets a comma delimited list of roles that are allowed to access the resource.
         /// </summary>
-        string Roles { get; set; }
+        string? Roles { get; set; }
 
         /// <summary>
         /// Gets or sets a comma delimited list of schemes from which user information is constructed.
         /// </summary>
-        string AuthenticationSchemes { get; set; }
+        string? AuthenticationSchemes { get; set; }
     }
 }

+ 1 - 0
src/Http/Metadata/src/Microsoft.AspNetCore.Metadata.csproj

@@ -7,6 +7,7 @@
     <NoWarn>$(NoWarn);CS1591</NoWarn>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <PackageTags>aspnetcore</PackageTags>
+    <Nullable>enable</Nullable>
   </PropertyGroup>
 
 </Project>

+ 1 - 0
src/Http/Routing.Abstractions/ref/Microsoft.AspNetCore.Routing.Abstractions.csproj

@@ -2,6 +2,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <TargetFrameworks>$(DefaultNetCoreTargetFramework)</TargetFrameworks>
+    <Nullable>annotations</Nullable>
   </PropertyGroup>
   <ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'">
     <Compile Include="Microsoft.AspNetCore.Routing.Abstractions.netcoreapp.cs" />

+ 8 - 8
src/Http/Routing.Abstractions/ref/Microsoft.AspNetCore.Routing.Abstractions.netcoreapp.cs

@@ -30,10 +30,10 @@ namespace Microsoft.AspNetCore.Routing
     public abstract partial class LinkGenerator
     {
         protected LinkGenerator() { }
-        public abstract string GetPathByAddress<TAddress>(Microsoft.AspNetCore.Http.HttpContext httpContext, TAddress address, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteValueDictionary ambientValues = null, Microsoft.AspNetCore.Http.PathString? pathBase = default(Microsoft.AspNetCore.Http.PathString?), Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions options = null);
-        public abstract string GetPathByAddress<TAddress>(TAddress address, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Http.PathString pathBase = default(Microsoft.AspNetCore.Http.PathString), Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions options = null);
-        public abstract string GetUriByAddress<TAddress>(Microsoft.AspNetCore.Http.HttpContext httpContext, TAddress address, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteValueDictionary ambientValues = null, string scheme = null, Microsoft.AspNetCore.Http.HostString? host = default(Microsoft.AspNetCore.Http.HostString?), Microsoft.AspNetCore.Http.PathString? pathBase = default(Microsoft.AspNetCore.Http.PathString?), Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions options = null);
-        public abstract string GetUriByAddress<TAddress>(TAddress address, Microsoft.AspNetCore.Routing.RouteValueDictionary values, string scheme, Microsoft.AspNetCore.Http.HostString host, Microsoft.AspNetCore.Http.PathString pathBase = default(Microsoft.AspNetCore.Http.PathString), Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions options = null);
+        public abstract string GetPathByAddress<TAddress>(Microsoft.AspNetCore.Http.HttpContext httpContext, TAddress address, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteValueDictionary? ambientValues = null, Microsoft.AspNetCore.Http.PathString? pathBase = default(Microsoft.AspNetCore.Http.PathString?), Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions? options = null);
+        public abstract string GetPathByAddress<TAddress>(TAddress address, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Http.PathString pathBase = default(Microsoft.AspNetCore.Http.PathString), Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions? options = null);
+        public abstract string GetUriByAddress<TAddress>(Microsoft.AspNetCore.Http.HttpContext httpContext, TAddress address, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteValueDictionary? ambientValues = null, string? scheme = null, Microsoft.AspNetCore.Http.HostString? host = default(Microsoft.AspNetCore.Http.HostString?), Microsoft.AspNetCore.Http.PathString? pathBase = default(Microsoft.AspNetCore.Http.PathString?), Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions? options = null);
+        public abstract string GetUriByAddress<TAddress>(TAddress address, Microsoft.AspNetCore.Routing.RouteValueDictionary values, string scheme, Microsoft.AspNetCore.Http.HostString host, Microsoft.AspNetCore.Http.PathString pathBase = default(Microsoft.AspNetCore.Http.PathString), Microsoft.AspNetCore.Http.FragmentString fragment = default(Microsoft.AspNetCore.Http.FragmentString), Microsoft.AspNetCore.Routing.LinkOptions? options = null);
     }
     public partial class LinkOptions
     {
@@ -45,7 +45,7 @@ namespace Microsoft.AspNetCore.Routing
     public partial class RouteContext
     {
         public RouteContext(Microsoft.AspNetCore.Http.HttpContext httpContext) { }
-        public Microsoft.AspNetCore.Http.RequestDelegate Handler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
+        public Microsoft.AspNetCore.Http.RequestDelegate? Handler { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
         public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
         public Microsoft.AspNetCore.Routing.RouteData RouteData { get { throw null; } set { } }
     }
@@ -75,15 +75,15 @@ namespace Microsoft.AspNetCore.Routing
     public static partial class RoutingHttpContextExtensions
     {
         public static Microsoft.AspNetCore.Routing.RouteData GetRouteData(this Microsoft.AspNetCore.Http.HttpContext httpContext) { throw null; }
-        public static object GetRouteValue(this Microsoft.AspNetCore.Http.HttpContext httpContext, string key) { throw null; }
+        public static object? GetRouteValue(this Microsoft.AspNetCore.Http.HttpContext httpContext, string key) { throw null; }
     }
     public partial class VirtualPathContext
     {
         public VirtualPathContext(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.RouteValueDictionary ambientValues, Microsoft.AspNetCore.Routing.RouteValueDictionary values) { }
-        public VirtualPathContext(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.RouteValueDictionary ambientValues, Microsoft.AspNetCore.Routing.RouteValueDictionary values, string routeName) { }
+        public VirtualPathContext(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.RouteValueDictionary ambientValues, Microsoft.AspNetCore.Routing.RouteValueDictionary values, string? routeName) { }
         public Microsoft.AspNetCore.Routing.RouteValueDictionary AmbientValues { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
         public Microsoft.AspNetCore.Http.HttpContext HttpContext { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
-        public string RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
+        public string? RouteName { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
         public Microsoft.AspNetCore.Routing.RouteValueDictionary Values { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
     }
     public partial class VirtualPathData

+ 8 - 8
src/Http/Routing.Abstractions/src/LinkGenerator.cs

@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// Copyright (c) .NET Foundation. All rights reserved.
 // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
 
 using Microsoft.AspNetCore.Http;
@@ -45,10 +45,10 @@ namespace Microsoft.AspNetCore.Routing
             HttpContext httpContext,
             TAddress address,
             RouteValueDictionary values,
-            RouteValueDictionary ambientValues = default,
+            RouteValueDictionary? ambientValues = default,
             PathString? pathBase = default,
             FragmentString fragment = default,
-            LinkOptions options = default);
+            LinkOptions? options = default);
 
         /// <summary>
         /// Generates a URI with an absolute path based on the provided values.
@@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Routing
             RouteValueDictionary values,
             PathString pathBase = default,
             FragmentString fragment = default,
-            LinkOptions options = default);
+            LinkOptions? options = default);
 
         /// <summary>
         /// Generates an absolute URI based on the provided values and <see cref="HttpContext"/>.
@@ -106,12 +106,12 @@ namespace Microsoft.AspNetCore.Routing
             HttpContext httpContext,
             TAddress address,
             RouteValueDictionary values,
-            RouteValueDictionary ambientValues = default,
-            string scheme = default,
+            RouteValueDictionary? ambientValues = default,
+            string? scheme = default,
             HostString? host = default,
             PathString? pathBase = default,
             FragmentString fragment = default,
-            LinkOptions options = default);
+            LinkOptions? options = default);
 
         /// <summary>
         /// Generates an absolute URI based on the provided values.
@@ -146,6 +146,6 @@ namespace Microsoft.AspNetCore.Routing
             HostString host,
             PathString pathBase = default,
             FragmentString fragment = default,
-            LinkOptions options = default);
+            LinkOptions? options = default);
     }
 }

+ 2 - 1
src/Http/Routing.Abstractions/src/Microsoft.AspNetCore.Routing.Abstractions.csproj

@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
     <Description>ASP.NET Core abstractions for routing requests to application logic and for generating links.
@@ -11,6 +11,7 @@ Microsoft.AspNetCore.Routing.RouteData</Description>
     <GenerateDocumentationFile>true</GenerateDocumentationFile>
     <PackageTags>aspnetcore;routing</PackageTags>
     <IsPackable>false</IsPackable>
+    <Nullable>annotations</Nullable>
   </PropertyGroup>
 
   <ItemGroup>

+ 2 - 2
src/Http/Routing.Abstractions/src/RouteContext.cs

@@ -19,7 +19,7 @@ namespace Microsoft.AspNetCore.Routing
         /// <param name="httpContext">The <see cref="Http.HttpContext"/> associated with the current request.</param>
         public RouteContext(HttpContext httpContext)
         {
-            HttpContext = httpContext;
+            HttpContext = httpContext ?? throw new ArgumentNullException(nameof(httpContext));
 
             RouteData = new RouteData();
         }
@@ -28,7 +28,7 @@ namespace Microsoft.AspNetCore.Routing
         /// Gets or sets the handler for the request. An <see cref="IRouter"/> should set <see cref="Handler"/>
         /// when it matches.
         /// </summary>
-        public RequestDelegate Handler { get; set; }
+        public RequestDelegate? Handler { get; set; }
 
         /// <summary>
         /// Gets the <see cref="Http.HttpContext"/> associated with the current request.

+ 1 - 1
src/Http/Routing.Abstractions/src/RoutingHttpContextExtensions.cs

@@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Routing
         /// <param name="httpContext">The <see cref="HttpContext"/> associated with the current request.</param>
         /// <param name="key">The key of the route value.</param>
         /// <returns>The corresponding route value, or null.</returns>
-        public static object GetRouteValue(this HttpContext httpContext, string key)
+        public static object? GetRouteValue(this HttpContext httpContext, string key)
         {
             if (httpContext == null)
             {

+ 2 - 2
src/Http/Routing.Abstractions/src/VirtualPathContext.cs

@@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Routing
             HttpContext httpContext,
             RouteValueDictionary ambientValues,
             RouteValueDictionary values,
-            string routeName)
+            string? routeName)
         {
             HttpContext = httpContext;
             AmbientValues = ambientValues;
@@ -56,7 +56,7 @@ namespace Microsoft.AspNetCore.Routing
         /// <summary>
         /// Gets the name of the route to use for virtual path generation.
         /// </summary>
-        public string RouteName { get; }
+        public string? RouteName { get; }
 
         /// <summary>
         /// Gets or sets the set of new values provided for virtual path generation.

+ 1 - 0
src/Http/Routing/ref/Microsoft.AspNetCore.Routing.csproj

@@ -2,6 +2,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <TargetFrameworks>$(DefaultNetCoreTargetFramework)</TargetFrameworks>
+    <Nullable>annotations</Nullable>
   </PropertyGroup>
   <ItemGroup Condition="'$(TargetFramework)' == '$(DefaultNetCoreTargetFramework)'">
     <Compile Include="Microsoft.AspNetCore.Routing.netcoreapp.cs" />

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików