Annotate Microsoft.AspNetCore.Http with nullable attributes (#22928)

* Annotate Microsoft.AspNetCore.Http with nullable attributes

* Annotate Hosting with nullable
This commit is contained in:
Pranav K 2020-06-15 16:29:19 -07:00 committed by GitHub
parent c93b61156d
commit 8efcca43ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
63 changed files with 306 additions and 295 deletions

View File

@ -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.Hosting.Abstractions.netcoreapp.cs" />

View File

@ -93,8 +93,8 @@ namespace Microsoft.AspNetCore.Hosting
Microsoft.AspNetCore.Hosting.IWebHostBuilder ConfigureAppConfiguration(System.Action<Microsoft.AspNetCore.Hosting.WebHostBuilderContext, Microsoft.Extensions.Configuration.IConfigurationBuilder> configureDelegate);
Microsoft.AspNetCore.Hosting.IWebHostBuilder ConfigureServices(System.Action<Microsoft.AspNetCore.Hosting.WebHostBuilderContext, Microsoft.Extensions.DependencyInjection.IServiceCollection> configureServices);
Microsoft.AspNetCore.Hosting.IWebHostBuilder ConfigureServices(System.Action<Microsoft.Extensions.DependencyInjection.IServiceCollection> configureServices);
string GetSetting(string key);
Microsoft.AspNetCore.Hosting.IWebHostBuilder UseSetting(string key, string value);
string? GetSetting(string key);
Microsoft.AspNetCore.Hosting.IWebHostBuilder UseSetting(string key, string? value);
}
public partial interface IWebHostEnvironment : Microsoft.Extensions.Hosting.IHostEnvironment
{

View File

@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Hosting
/// </summary>
/// <param name="key">The key of the setting to look up.</param>
/// <returns>The value the setting currently contains.</returns>
string GetSetting(string key);
string? GetSetting(string key);
/// <summary>
/// Add or replace a setting in the configuration.
@ -58,6 +58,6 @@ namespace Microsoft.AspNetCore.Hosting
/// <param name="key">The key of the setting to add or replace.</param>
/// <param name="value">The value of the setting to add or replace.</param>
/// <returns>The <see cref="IWebHostBuilder"/>.</returns>
IWebHostBuilder UseSetting(string key, string value);
IWebHostBuilder UseSetting(string key, string? value);
}
}
}

View File

@ -8,6 +8,7 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>aspnetcore;hosting</PackageTags>
<IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>

View File

@ -13,11 +13,11 @@ namespace Microsoft.AspNetCore.Hosting
/// <summary>
/// The <see cref="IWebHostEnvironment" /> initialized by the <see cref="IWebHost" />.
/// </summary>
public IWebHostEnvironment HostingEnvironment { get; set; }
public IWebHostEnvironment HostingEnvironment { get; set; } = default!;
/// <summary>
/// The <see cref="IConfiguration" /> containing the merged configuration of the application and the <see cref="IWebHost" />.
/// </summary>
public IConfiguration Configuration { get; set; }
public IConfiguration Configuration { get; set; } = default!;
}
}

View File

@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Builder
public partial interface IApplicationBuilder
{
System.IServiceProvider ApplicationServices { get; set; }
System.Collections.Generic.IDictionary<string, object> Properties { get; }
System.Collections.Generic.IDictionary<string, object?> Properties { get; }
Microsoft.AspNetCore.Http.Features.IFeatureCollection ServerFeatures { get; }
Microsoft.AspNetCore.Http.RequestDelegate Build();
Microsoft.AspNetCore.Builder.IApplicationBuilder New();
@ -108,13 +108,13 @@ namespace Microsoft.AspNetCore.Http
public abstract partial class ConnectionInfo
{
protected ConnectionInfo() { }
public abstract System.Security.Cryptography.X509Certificates.X509Certificate2 ClientCertificate { get; set; }
public abstract System.Security.Cryptography.X509Certificates.X509Certificate2? ClientCertificate { get; set; }
public abstract string Id { get; set; }
public abstract System.Net.IPAddress LocalIpAddress { get; set; }
public abstract System.Net.IPAddress? LocalIpAddress { get; set; }
public abstract int LocalPort { get; set; }
public abstract System.Net.IPAddress RemoteIpAddress { get; set; }
public abstract System.Net.IPAddress? RemoteIpAddress { get; set; }
public abstract int RemotePort { get; set; }
public abstract System.Threading.Tasks.Task<System.Security.Cryptography.X509Certificates.X509Certificate2> GetClientCertificateAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
public abstract System.Threading.Tasks.Task<System.Security.Cryptography.X509Certificates.X509Certificate2?> GetClientCertificateAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken));
}
public partial class CookieBuilder
{
@ -231,7 +231,7 @@ namespace Microsoft.AspNetCore.Http
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; }
@ -326,7 +326,7 @@ namespace Microsoft.AspNetCore.Http
}
public partial interface IHttpContextAccessor
{
Microsoft.AspNetCore.Http.HttpContext HttpContext { get; set; }
Microsoft.AspNetCore.Http.HttpContext? HttpContext { get; set; }
}
public partial interface IHttpContextFactory
{

View File

@ -15,16 +15,16 @@ namespace Microsoft.AspNetCore.Http
/// </summary>
public abstract string Id { get; set; }
public abstract IPAddress RemoteIpAddress { get; set; }
public abstract IPAddress? RemoteIpAddress { get; set; }
public abstract int RemotePort { get; set; }
public abstract IPAddress LocalIpAddress { get; set; }
public abstract IPAddress? LocalIpAddress { get; set; }
public abstract int LocalPort { get; set; }
public abstract X509Certificate2 ClientCertificate { get; set; }
public abstract X509Certificate2? ClientCertificate { get; set; }
public abstract Task<X509Certificate2> GetClientCertificateAsync(CancellationToken cancellationToken = new CancellationToken());
public abstract Task<X509Certificate2?> GetClientCertificateAsync(CancellationToken cancellationToken = new CancellationToken());
}
}

View File

@ -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.

View File

@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Builder
/// <summary>
/// Gets a key/value collection that can be used to share data between middleware.
/// </summary>
IDictionary<string, object> Properties { get; }
IDictionary<string, object?> Properties { get; }
/// <summary>
/// Adds a middleware delegate to the application's request pipeline.

View File

@ -15,6 +15,6 @@ namespace Microsoft.AspNetCore.Http
/// <summary>
/// Gets or sets the current <see cref="HttpContext"/>. Returns <see langword="null" /> if there is no active <see cref="HttpContext" />.
/// </summary>
HttpContext HttpContext { get; set; }
HttpContext? HttpContext { get; set; }
}
}

View File

@ -38,8 +38,8 @@ namespace Microsoft.AspNetCore.Http
}
public partial interface IFormFileCollection : System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Http.IFormFile>, System.Collections.Generic.IReadOnlyCollection<Microsoft.AspNetCore.Http.IFormFile>, System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Http.IFormFile>, System.Collections.IEnumerable
{
Microsoft.AspNetCore.Http.IFormFile this[string name] { get; }
Microsoft.AspNetCore.Http.IFormFile GetFile(string name);
Microsoft.AspNetCore.Http.IFormFile? this[string name] { get; }
Microsoft.AspNetCore.Http.IFormFile? GetFile(string name);
System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Http.IFormFile> GetFiles(string name);
}
public partial interface IHeaderDictionary : System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>>, System.Collections.Generic.IDictionary<string, Microsoft.Extensions.Primitives.StringValues>, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>>, System.Collections.IEnumerable
@ -58,10 +58,10 @@ namespace Microsoft.AspNetCore.Http
public partial interface IRequestCookieCollection : System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, string>>, System.Collections.IEnumerable
{
int Count { get; }
string this[string key] { get; }
string? this[string key] { get; }
System.Collections.Generic.ICollection<string> Keys { get; }
bool ContainsKey(string key);
bool TryGetValue(string key, out string value);
bool TryGetValue(string key, [System.Diagnostics.CodeAnalysis.MaybeNullWhenAttribute(false)] out string? value);
}
public partial interface IResponseCookies
{
@ -121,8 +121,8 @@ namespace Microsoft.AspNetCore.Http.Features
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>([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; }
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) { }
}
@ -152,7 +152,7 @@ namespace Microsoft.AspNetCore.Http.Features
}
public partial interface IFormFeature
{
Microsoft.AspNetCore.Http.IFormCollection Form { get; set; }
Microsoft.AspNetCore.Http.IFormCollection? Form { get; set; }
bool HasFormContentType { get; }
Microsoft.AspNetCore.Http.IFormCollection ReadForm();
System.Threading.Tasks.Task<Microsoft.AspNetCore.Http.IFormCollection> ReadFormAsync(System.Threading.CancellationToken cancellationToken);
@ -170,9 +170,9 @@ namespace Microsoft.AspNetCore.Http.Features
public partial interface IHttpConnectionFeature
{
string ConnectionId { get; set; }
System.Net.IPAddress LocalIpAddress { get; set; }
System.Net.IPAddress? LocalIpAddress { get; set; }
int LocalPort { get; set; }
System.Net.IPAddress RemoteIpAddress { get; set; }
System.Net.IPAddress? RemoteIpAddress { get; set; }
int RemotePort { get; set; }
}
public partial interface IHttpMaxRequestBodySizeFeature
@ -225,7 +225,7 @@ namespace Microsoft.AspNetCore.Http.Features
System.IO.Stream Body { get; set; }
bool HasStarted { get; }
Microsoft.AspNetCore.Http.IHeaderDictionary Headers { get; set; }
string ReasonPhrase { get; set; }
string? ReasonPhrase { get; set; }
int StatusCode { get; set; }
void OnCompleted(System.Func<object, System.Threading.Tasks.Task> callback, object state);
void OnStarting(System.Func<object, System.Threading.Tasks.Task> callback, object state);
@ -255,7 +255,7 @@ namespace Microsoft.AspNetCore.Http.Features
}
public partial interface IItemsFeature
{
System.Collections.Generic.IDictionary<object, object> Items { get; set; }
System.Collections.Generic.IDictionary<object, object?> Items { get; set; }
}
public partial interface IQueryFeature
{
@ -287,8 +287,8 @@ namespace Microsoft.AspNetCore.Http.Features
}
public partial interface ITlsConnectionFeature
{
System.Security.Cryptography.X509Certificates.X509Certificate2 ClientCertificate { get; set; }
System.Threading.Tasks.Task<System.Security.Cryptography.X509Certificates.X509Certificate2> GetClientCertificateAsync(System.Threading.CancellationToken cancellationToken);
System.Security.Cryptography.X509Certificates.X509Certificate2? ClientCertificate { get; set; }
System.Threading.Tasks.Task<System.Security.Cryptography.X509Certificates.X509Certificate2?> GetClientCertificateAsync(System.Threading.CancellationToken cancellationToken);
}
public partial interface ITlsTokenBindingFeature
{
@ -309,6 +309,6 @@ namespace Microsoft.AspNetCore.Http.Features.Authentication
{
public partial interface IHttpAuthenticationFeature
{
System.Security.Claims.ClaimsPrincipal User { get; set; }
System.Security.Claims.ClaimsPrincipal? User { get; set; }
}
}

View File

@ -38,8 +38,8 @@ namespace Microsoft.AspNetCore.Http
}
public partial interface IFormFileCollection : System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Http.IFormFile>, System.Collections.Generic.IReadOnlyCollection<Microsoft.AspNetCore.Http.IFormFile>, System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Http.IFormFile>, System.Collections.IEnumerable
{
Microsoft.AspNetCore.Http.IFormFile this[string name] { get; }
Microsoft.AspNetCore.Http.IFormFile GetFile(string name);
Microsoft.AspNetCore.Http.IFormFile? this[string name] { get; }
Microsoft.AspNetCore.Http.IFormFile? GetFile(string name);
System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Http.IFormFile> GetFiles(string name);
}
public partial interface IHeaderDictionary : System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>>, System.Collections.Generic.IDictionary<string, Microsoft.Extensions.Primitives.StringValues>, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>>, System.Collections.IEnumerable
@ -58,10 +58,10 @@ namespace Microsoft.AspNetCore.Http
public partial interface IRequestCookieCollection : System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, string>>, System.Collections.IEnumerable
{
int Count { get; }
string this[string key] { get; }
string? this[string key] { get; }
System.Collections.Generic.ICollection<string> Keys { get; }
bool ContainsKey(string key);
bool TryGetValue(string key, out string value);
bool TryGetValue(string key, out string? value);
}
public partial interface IResponseCookies
{
@ -118,8 +118,8 @@ namespace Microsoft.AspNetCore.Http.Features
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>(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; }
[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) { }
}
@ -148,7 +148,7 @@ namespace Microsoft.AspNetCore.Http.Features
}
public partial interface IFormFeature
{
Microsoft.AspNetCore.Http.IFormCollection Form { get; set; }
Microsoft.AspNetCore.Http.IFormCollection? Form { get; set; }
bool HasFormContentType { get; }
Microsoft.AspNetCore.Http.IFormCollection ReadForm();
System.Threading.Tasks.Task<Microsoft.AspNetCore.Http.IFormCollection> ReadFormAsync(System.Threading.CancellationToken cancellationToken);
@ -166,9 +166,9 @@ namespace Microsoft.AspNetCore.Http.Features
public partial interface IHttpConnectionFeature
{
string ConnectionId { get; set; }
System.Net.IPAddress LocalIpAddress { get; set; }
System.Net.IPAddress? LocalIpAddress { get; set; }
int LocalPort { get; set; }
System.Net.IPAddress RemoteIpAddress { get; set; }
System.Net.IPAddress? RemoteIpAddress { get; set; }
int RemotePort { get; set; }
}
public partial interface IHttpMaxRequestBodySizeFeature
@ -221,7 +221,7 @@ namespace Microsoft.AspNetCore.Http.Features
System.IO.Stream Body { get; set; }
bool HasStarted { get; }
Microsoft.AspNetCore.Http.IHeaderDictionary Headers { get; set; }
string ReasonPhrase { get; set; }
string? ReasonPhrase { get; set; }
int StatusCode { get; set; }
void OnCompleted(System.Func<object, System.Threading.Tasks.Task> callback, object state);
void OnStarting(System.Func<object, System.Threading.Tasks.Task> callback, object state);
@ -251,7 +251,7 @@ namespace Microsoft.AspNetCore.Http.Features
}
public partial interface IItemsFeature
{
System.Collections.Generic.IDictionary<object, object> Items { get; set; }
System.Collections.Generic.IDictionary<object, object?> Items { get; set; }
}
public partial interface IQueryFeature
{
@ -283,8 +283,8 @@ namespace Microsoft.AspNetCore.Http.Features
}
public partial interface ITlsConnectionFeature
{
System.Security.Cryptography.X509Certificates.X509Certificate2 ClientCertificate { get; set; }
System.Threading.Tasks.Task<System.Security.Cryptography.X509Certificates.X509Certificate2> GetClientCertificateAsync(System.Threading.CancellationToken cancellationToken);
System.Security.Cryptography.X509Certificates.X509Certificate2? ClientCertificate { get; set; }
System.Threading.Tasks.Task<System.Security.Cryptography.X509Certificates.X509Certificate2?> GetClientCertificateAsync(System.Threading.CancellationToken cancellationToken);
}
public partial interface ITlsTokenBindingFeature
{
@ -305,6 +305,6 @@ namespace Microsoft.AspNetCore.Http.Features.Authentication
{
public partial interface IHttpAuthenticationFeature
{
System.Security.Claims.ClaimsPrincipal User { get; set; }
System.Security.Claims.ClaimsPrincipal? User { get; set; }
}
}

View File

@ -8,6 +8,6 @@ namespace Microsoft.AspNetCore.Http.Features.Authentication
{
public interface IHttpAuthenticationFeature
{
ClaimsPrincipal User { get; set; }
ClaimsPrincipal? User { get; set; }
}
}

View File

@ -62,9 +62,9 @@ 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>(
[AllowNull, MaybeNull]ref TFeature cached,
[AllowNull, MaybeNull] ref TFeature cached,
TState state,
Func<TState, TFeature> factory) where TFeature : class
Func<TState, TFeature> factory) where TFeature : class?
{
var flush = false;
var revision = Collection?.Revision ?? ContextDisposed();
@ -80,7 +80,7 @@ namespace Microsoft.AspNetCore.Http.Features
}
// Update and cache clearing logic, when the fast-path in Fetch isn't applicable
private TFeature UpdateCached<TFeature, TState>(ref TFeature cached, TState state, Func<TState, TFeature> factory, int revision, bool flush) where TFeature : class
private TFeature UpdateCached<TFeature, TState>(ref TFeature cached, TState state, Func<TState, TFeature> factory, int revision, bool flush) where TFeature : class?
{
if (flush)
{
@ -108,8 +108,8 @@ namespace Microsoft.AspNetCore.Http.Features
return cached;
}
public TFeature Fetch<TFeature>([AllowNull, MaybeNull]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()
{

View File

@ -16,12 +16,12 @@ namespace Microsoft.AspNetCore.Http.Features
/// <summary>
/// The parsed form, if any.
/// </summary>
IFormCollection Form { get; set; }
IFormCollection? Form { get; set; }
/// <summary>
/// Parses the request body as a form.
/// </summary>
/// <returns></returns>
/// <returns>The <see cref="IFormCollection"/>.</returns>
IFormCollection ReadForm();
/// <summary>

View File

@ -17,7 +17,7 @@ namespace Microsoft.AspNetCore.Http
/// <returns>
/// The requested file, or null if it is not present.
/// </returns>
IFormFile this[string name] { get; }
IFormFile? this[string name] { get; }
/// <summary>
/// Gets the first file with the specified name.
@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Http
/// <returns>
/// The requested file, or null if it is not present.
/// </returns>
IFormFile GetFile(string name);
IFormFile? GetFile(string name);
/// <summary>
/// Gets an <see cref="IReadOnlyList{T}" /> containing the files of the

View File

@ -18,12 +18,12 @@ namespace Microsoft.AspNetCore.Http.Features
/// <summary>
/// The IPAddress of the client making the request. Note this may be for a proxy rather than the end user.
/// </summary>
IPAddress RemoteIpAddress { get; set; }
IPAddress? RemoteIpAddress { get; set; }
/// <summary>
/// The local IPAddress on which the request was received.
/// </summary>
IPAddress LocalIpAddress { get; set; }
IPAddress? LocalIpAddress { get; set; }
/// <summary>
/// The remote port of the client making the request.
@ -35,4 +35,4 @@ namespace Microsoft.AspNetCore.Http.Features
/// </summary>
int LocalPort { get; set; }
}
}
}

View File

@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Http.Features
/// <summary>
/// The reason-phrase as defined in RFC 7230. Note this field is no longer supported by HTTP/2.
/// </summary>
string ReasonPhrase { get; set; }
string? ReasonPhrase { get; set; }
/// <summary>
/// The response headers to send. Headers with multiple values will be emitted as multiple headers.

View File

@ -7,6 +7,6 @@ namespace Microsoft.AspNetCore.Http.Features
{
public interface IItemsFeature
{
IDictionary<object, object> Items { get; set; }
IDictionary<object, object?> Items { get; set; }
}
}
}

View File

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.AspNetCore.Http
{
@ -63,7 +64,7 @@ namespace Microsoft.AspNetCore.Http
/// <exception cref="System.ArgumentNullException">
/// key is null.
/// </exception>
bool TryGetValue(string key, out string value);
bool TryGetValue(string key, [MaybeNullWhen(false)] out string? value);
/// <summary>
/// Gets the value with the specified key.
@ -82,6 +83,6 @@ namespace Microsoft.AspNetCore.Http
/// <see cref="IDictionary{TKey, TValue}" />, as it will return <c>string.Empty</c> for missing entries
/// rather than throwing an Exception.
/// </remarks>
string this[string key] { get; }
string? this[string key] { get; }
}
}

View File

@ -12,12 +12,12 @@ namespace Microsoft.AspNetCore.Http.Features
/// <summary>
/// Synchronously retrieves the client certificate, if any.
/// </summary>
X509Certificate2 ClientCertificate { get; set; }
X509Certificate2? ClientCertificate { get; set; }
/// <summary>
/// Asynchronously retrieves the client certificate, if any.
/// </summary>
/// <returns></returns>
Task<X509Certificate2> GetClientCertificateAsync(CancellationToken cancellationToken);
Task<X509Certificate2?> GetClientCertificateAsync(CancellationToken cancellationToken);
}
}

View File

@ -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.netcoreapp.cs" />

View File

@ -8,7 +8,7 @@ namespace Microsoft.AspNetCore.Builder
public ApplicationBuilder(System.IServiceProvider serviceProvider) { }
public ApplicationBuilder(System.IServiceProvider serviceProvider, object server) { }
public System.IServiceProvider ApplicationServices { get { throw null; } set { } }
public System.Collections.Generic.IDictionary<string, object> Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public System.Collections.Generic.IDictionary<string, object?> Properties { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public Microsoft.AspNetCore.Http.Features.IFeatureCollection ServerFeatures { get { throw null; } }
public Microsoft.AspNetCore.Http.RequestDelegate Build() { throw null; }
public Microsoft.AspNetCore.Builder.IApplicationBuilder New() { throw null; }
@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Http
public int Port { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public string Scheme { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public string UnixPipePath { 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.AspNetCore.Http.BindingAddress Parse(string address) { throw null; }
public override string ToString() { throw null; }
@ -40,7 +40,7 @@ namespace Microsoft.AspNetCore.Http
public Microsoft.AspNetCore.Http.Features.FormOptions FormOptions { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public Microsoft.AspNetCore.Http.HttpContext HttpContext { get { throw null; } }
public override System.Collections.Generic.IDictionary<object, object> Items { get { throw null; } set { } }
public override System.Collections.Generic.IDictionary<object, object?> Items { get { throw null; } set { } }
public override Microsoft.AspNetCore.Http.HttpRequest Request { get { throw null; } }
public override System.Threading.CancellationToken RequestAborted { get { throw null; } set { } }
public override System.IServiceProvider RequestServices { get { throw null; } set { } }
@ -57,7 +57,7 @@ namespace Microsoft.AspNetCore.Http
public partial class FormCollection : Microsoft.AspNetCore.Http.IFormCollection, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>>, System.Collections.IEnumerable
{
public static readonly Microsoft.AspNetCore.Http.FormCollection Empty;
public FormCollection(System.Collections.Generic.Dictionary<string, Microsoft.Extensions.Primitives.StringValues> fields, Microsoft.AspNetCore.Http.IFormFileCollection files = null) { }
public FormCollection(System.Collections.Generic.Dictionary<string, Microsoft.Extensions.Primitives.StringValues>? fields, Microsoft.AspNetCore.Http.IFormFileCollection? files = null) { }
public int Count { get { throw null; } }
public Microsoft.AspNetCore.Http.IFormFileCollection Files { get { throw null; } }
public Microsoft.Extensions.Primitives.StringValues this[string key] { get { throw null; } }
@ -96,14 +96,14 @@ namespace Microsoft.AspNetCore.Http
public partial class FormFileCollection : System.Collections.Generic.List<Microsoft.AspNetCore.Http.IFormFile>, Microsoft.AspNetCore.Http.IFormFileCollection, System.Collections.Generic.IEnumerable<Microsoft.AspNetCore.Http.IFormFile>, System.Collections.Generic.IReadOnlyCollection<Microsoft.AspNetCore.Http.IFormFile>, System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Http.IFormFile>, System.Collections.IEnumerable
{
public FormFileCollection() { }
public Microsoft.AspNetCore.Http.IFormFile this[string name] { get { throw null; } }
public Microsoft.AspNetCore.Http.IFormFile GetFile(string name) { throw null; }
public Microsoft.AspNetCore.Http.IFormFile? this[string name] { get { throw null; } }
public Microsoft.AspNetCore.Http.IFormFile? GetFile(string name) { throw null; }
public System.Collections.Generic.IReadOnlyList<Microsoft.AspNetCore.Http.IFormFile> GetFiles(string name) { throw null; }
}
public partial class HeaderDictionary : Microsoft.AspNetCore.Http.IHeaderDictionary, System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>>, System.Collections.Generic.IDictionary<string, Microsoft.Extensions.Primitives.StringValues>, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>>, System.Collections.IEnumerable
{
public HeaderDictionary() { }
public HeaderDictionary(System.Collections.Generic.Dictionary<string, Microsoft.Extensions.Primitives.StringValues> store) { }
public HeaderDictionary(System.Collections.Generic.Dictionary<string, Microsoft.Extensions.Primitives.StringValues>? store) { }
public HeaderDictionary(int capacity) { }
public long? ContentLength { get { throw null; } set { } }
public int Count { get { throw null; } }
@ -139,15 +139,15 @@ namespace Microsoft.AspNetCore.Http
public partial class HttpContextAccessor : Microsoft.AspNetCore.Http.IHttpContextAccessor
{
public HttpContextAccessor() { }
public Microsoft.AspNetCore.Http.HttpContext HttpContext { get { throw null; } set { } }
public Microsoft.AspNetCore.Http.HttpContext? HttpContext { get { throw null; } set { } }
}
[System.ObsoleteAttribute("This is obsolete and will be removed in a future version. Use DefaultHttpContextFactory instead.")]
public partial class HttpContextFactory : Microsoft.AspNetCore.Http.IHttpContextFactory
{
public HttpContextFactory(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Http.Features.FormOptions> formOptions) { }
public HttpContextFactory(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Http.Features.FormOptions> formOptions, Microsoft.AspNetCore.Http.IHttpContextAccessor httpContextAccessor) { }
public HttpContextFactory(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Http.Features.FormOptions> formOptions, Microsoft.AspNetCore.Http.IHttpContextAccessor? httpContextAccessor) { }
public HttpContextFactory(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Http.Features.FormOptions> formOptions, Microsoft.Extensions.DependencyInjection.IServiceScopeFactory serviceScopeFactory) { }
public HttpContextFactory(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Http.Features.FormOptions> formOptions, Microsoft.Extensions.DependencyInjection.IServiceScopeFactory serviceScopeFactory, Microsoft.AspNetCore.Http.IHttpContextAccessor httpContextAccessor) { }
public HttpContextFactory(Microsoft.Extensions.Options.IOptions<Microsoft.AspNetCore.Http.Features.FormOptions> formOptions, Microsoft.Extensions.DependencyInjection.IServiceScopeFactory serviceScopeFactory, Microsoft.AspNetCore.Http.IHttpContextAccessor? httpContextAccessor) { }
public Microsoft.AspNetCore.Http.HttpContext Create(Microsoft.AspNetCore.Http.Features.IFeatureCollection featureCollection) { throw null; }
public void Dispose(Microsoft.AspNetCore.Http.HttpContext httpContext) { }
}
@ -161,7 +161,7 @@ namespace Microsoft.AspNetCore.Http
public partial class MiddlewareFactory : Microsoft.AspNetCore.Http.IMiddlewareFactory
{
public MiddlewareFactory(System.IServiceProvider serviceProvider) { }
public Microsoft.AspNetCore.Http.IMiddleware Create(System.Type middlewareType) { throw null; }
public Microsoft.AspNetCore.Http.IMiddleware? Create(System.Type middlewareType) { throw null; }
public void Release(Microsoft.AspNetCore.Http.IMiddleware middleware) { }
}
public partial class QueryCollection : Microsoft.AspNetCore.Http.IQueryCollection, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, Microsoft.Extensions.Primitives.StringValues>>, System.Collections.IEnumerable
@ -204,7 +204,7 @@ namespace Microsoft.AspNetCore.Http
{
public StreamResponseBodyFeature(System.IO.Stream stream) { }
public StreamResponseBodyFeature(System.IO.Stream stream, Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature priorFeature) { }
public Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature PriorFeature { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public Microsoft.AspNetCore.Http.Features.IHttpResponseBodyFeature? PriorFeature { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public System.IO.Stream Stream { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } }
public System.IO.Pipelines.PipeWriter Writer { get { throw null; } }
[System.Diagnostics.DebuggerStepThroughAttribute]
@ -228,7 +228,7 @@ namespace Microsoft.AspNetCore.Http.Features
public FormFeature(Microsoft.AspNetCore.Http.HttpRequest request) { }
public FormFeature(Microsoft.AspNetCore.Http.HttpRequest request, Microsoft.AspNetCore.Http.Features.FormOptions options) { }
public FormFeature(Microsoft.AspNetCore.Http.IFormCollection form) { }
public Microsoft.AspNetCore.Http.IFormCollection Form { get { throw null; } set { } }
public Microsoft.AspNetCore.Http.IFormCollection? Form { get { throw null; } set { } }
public bool HasFormContentType { get { throw null; } }
public Microsoft.AspNetCore.Http.IFormCollection ReadForm() { throw null; }
public System.Threading.Tasks.Task<Microsoft.AspNetCore.Http.IFormCollection> ReadFormAsync() { throw null; }
@ -256,9 +256,9 @@ namespace Microsoft.AspNetCore.Http.Features
{
public HttpConnectionFeature() { }
public string ConnectionId { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public System.Net.IPAddress LocalIpAddress { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public System.Net.IPAddress? LocalIpAddress { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public int LocalPort { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public System.Net.IPAddress RemoteIpAddress { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public System.Net.IPAddress? RemoteIpAddress { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public int RemotePort { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
}
public partial class HttpRequestFeature : Microsoft.AspNetCore.Http.Features.IHttpRequestFeature
@ -291,7 +291,7 @@ namespace Microsoft.AspNetCore.Http.Features
public System.IO.Stream Body { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public virtual bool HasStarted { get { throw null; } }
public Microsoft.AspNetCore.Http.IHeaderDictionary Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public string ReasonPhrase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public string? ReasonPhrase { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public int StatusCode { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public virtual void OnCompleted(System.Func<object, System.Threading.Tasks.Task> callback, object state) { }
public virtual void OnStarting(System.Func<object, System.Threading.Tasks.Task> callback, object state) { }
@ -299,7 +299,7 @@ namespace Microsoft.AspNetCore.Http.Features
public partial class ItemsFeature : Microsoft.AspNetCore.Http.Features.IItemsFeature
{
public ItemsFeature() { }
public System.Collections.Generic.IDictionary<object, object> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public System.Collections.Generic.IDictionary<object, object?> Items { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
}
public partial class QueryFeature : Microsoft.AspNetCore.Http.Features.IQueryFeature
{
@ -320,7 +320,7 @@ namespace Microsoft.AspNetCore.Http.Features
}
public partial class RequestServicesFeature : Microsoft.AspNetCore.Http.Features.IServiceProvidersFeature, System.IAsyncDisposable, System.IDisposable
{
public RequestServicesFeature(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.Extensions.DependencyInjection.IServiceScopeFactory scopeFactory) { }
public RequestServicesFeature(Microsoft.AspNetCore.Http.HttpContext context, Microsoft.Extensions.DependencyInjection.IServiceScopeFactory? scopeFactory) { }
public System.IServiceProvider RequestServices { get { throw null; } set { } }
public void Dispose() { }
public System.Threading.Tasks.ValueTask DisposeAsync() { throw null; }
@ -328,7 +328,7 @@ namespace Microsoft.AspNetCore.Http.Features
public partial class ResponseCookiesFeature : Microsoft.AspNetCore.Http.Features.IResponseCookiesFeature
{
public ResponseCookiesFeature(Microsoft.AspNetCore.Http.Features.IFeatureCollection features) { }
public ResponseCookiesFeature(Microsoft.AspNetCore.Http.Features.IFeatureCollection features, Microsoft.Extensions.ObjectPool.ObjectPool<System.Text.StringBuilder> builderPool) { }
public ResponseCookiesFeature(Microsoft.AspNetCore.Http.Features.IFeatureCollection features, Microsoft.Extensions.ObjectPool.ObjectPool<System.Text.StringBuilder>? builderPool) { }
public Microsoft.AspNetCore.Http.IResponseCookies Cookies { get { throw null; } }
}
public partial class RouteValuesFeature : Microsoft.AspNetCore.Http.Features.IRouteValuesFeature
@ -344,8 +344,8 @@ namespace Microsoft.AspNetCore.Http.Features
public partial class TlsConnectionFeature : Microsoft.AspNetCore.Http.Features.ITlsConnectionFeature
{
public TlsConnectionFeature() { }
public System.Security.Cryptography.X509Certificates.X509Certificate2 ClientCertificate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public System.Threading.Tasks.Task<System.Security.Cryptography.X509Certificates.X509Certificate2> GetClientCertificateAsync(System.Threading.CancellationToken cancellationToken) { throw null; }
public System.Security.Cryptography.X509Certificates.X509Certificate2? ClientCertificate { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public System.Threading.Tasks.Task<System.Security.Cryptography.X509Certificates.X509Certificate2?> GetClientCertificateAsync(System.Threading.CancellationToken cancellationToken) { throw null; }
}
}
namespace Microsoft.AspNetCore.Http.Features.Authentication
@ -353,7 +353,7 @@ namespace Microsoft.AspNetCore.Http.Features.Authentication
public partial class HttpAuthenticationFeature : Microsoft.AspNetCore.Http.Features.Authentication.IHttpAuthenticationFeature
{
public HttpAuthenticationFeature() { }
public System.Security.Claims.ClaimsPrincipal User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public System.Security.Claims.ClaimsPrincipal? User { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
}
}
namespace Microsoft.Extensions.DependencyInjection

View File

@ -12,10 +12,10 @@ namespace Microsoft.AspNetCore.Http
{
private const string UnixPipeHostPrefix = "unix:/";
public string Host { get; private set; }
public string PathBase { get; private set; }
public string Host { get; private set; } = default!;
public string PathBase { get; private set; } = default!;
public int Port { get; internal set; }
public string Scheme { get; private set; }
public string Scheme { get; private set; } = default!;
public bool IsUnixPipe
{
@ -62,7 +62,7 @@ namespace Microsoft.AspNetCore.Http
return ToString().GetHashCode();
}
public override bool Equals(object obj)
public override bool Equals(object? obj)
{
var other = obj as BindingAddress;
if (other == null)

View File

@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
@ -20,7 +21,7 @@ namespace Microsoft.AspNetCore.Builder
public ApplicationBuilder(IServiceProvider serviceProvider)
{
Properties = new Dictionary<string, object>(StringComparer.Ordinal);
Properties = new Dictionary<string, object?>(StringComparer.Ordinal);
ApplicationServices = serviceProvider;
}
@ -32,14 +33,14 @@ namespace Microsoft.AspNetCore.Builder
private ApplicationBuilder(ApplicationBuilder builder)
{
Properties = new CopyOnWriteDictionary<string, object>(builder.Properties, StringComparer.Ordinal);
Properties = new CopyOnWriteDictionary<string, object?>(builder.Properties, StringComparer.Ordinal);
}
public IServiceProvider ApplicationServices
{
get
{
return GetProperty<IServiceProvider>(ApplicationServicesKey);
return GetProperty<IServiceProvider>(ApplicationServicesKey)!;
}
set
{
@ -51,16 +52,16 @@ namespace Microsoft.AspNetCore.Builder
{
get
{
return GetProperty<IFeatureCollection>(ServerFeaturesKey);
return GetProperty<IFeatureCollection>(ServerFeaturesKey)!;
}
}
public IDictionary<string, object> Properties { get; }
public IDictionary<string, object?> Properties { get; }
[return: MaybeNull]
private T GetProperty<T>(string key)
{
object value;
return Properties.TryGetValue(key, out value) ? (T)value : default(T);
return Properties.TryGetValue(key, out var value) ? (T)value : default(T);
}
private void SetProperty<T>(string key, T value)
@ -90,7 +91,7 @@ namespace Microsoft.AspNetCore.Builder
if (endpointRequestDelegate != null)
{
var message =
$"The request reached the end of the pipeline without executing the endpoint: '{endpoint.DisplayName}'. " +
$"The request reached the end of the pipeline without executing the endpoint: '{endpoint!.DisplayName}'. " +
$"Please register the EndpointMiddleware using '{nameof(IApplicationBuilder)}.UseEndpoints(...)' if using " +
$"routing.";
throw new InvalidOperationException(message);

View File

@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Security.Claims;
using System.Threading;
@ -24,7 +25,7 @@ namespace Microsoft.AspNetCore.Http
private readonly static Func<IFeatureCollection, IHttpAuthenticationFeature> _newHttpAuthenticationFeature = f => new HttpAuthenticationFeature();
private readonly static Func<IFeatureCollection, IHttpRequestLifetimeFeature> _newHttpRequestLifetimeFeature = f => new HttpRequestLifetimeFeature();
private readonly static Func<IFeatureCollection, ISessionFeature> _newSessionFeature = f => new DefaultSessionFeature();
private readonly static Func<IFeatureCollection, ISessionFeature> _nullSessionFeature = f => null;
private readonly static Func<IFeatureCollection, ISessionFeature?> _nullSessionFeature = f => null;
private readonly static Func<IFeatureCollection, IHttpRequestIdentifierFeature> _newHttpRequestIdentifierFeature = f => new HttpRequestIdentifierFeature();
private FeatureReferences<FeatureInterfaces> _features;
@ -32,8 +33,8 @@ namespace Microsoft.AspNetCore.Http
private readonly DefaultHttpRequest _request;
private readonly DefaultHttpResponse _response;
private DefaultConnectionInfo _connection;
private DefaultWebSocketManager _websockets;
private DefaultConnectionInfo? _connection;
private DefaultWebSocketManager? _websockets;
/// <summary>
/// Initializes a new instance of the <see cref="DefaultHttpContext"/> class.
@ -92,7 +93,7 @@ namespace Microsoft.AspNetCore.Http
/// <returns>
/// <see cref="FormOptions"/>
/// </returns>
public FormOptions FormOptions { get; set; }
public FormOptions FormOptions { get; set; } = default!;
/// <summary>
/// Gets or sets the <see cref="IServiceScopeFactory" /> for this instance.
@ -100,29 +101,28 @@ namespace Microsoft.AspNetCore.Http
/// <returns>
/// <see cref="IServiceScopeFactory"/>
/// </returns>
public IServiceScopeFactory ServiceScopeFactory { get; set; }
public IServiceScopeFactory ServiceScopeFactory { get; set; } = default!;
private IItemsFeature ItemsFeature =>
_features.Fetch(ref _features.Cache.Items, _newItemsFeature);
_features.Fetch(ref _features.Cache.Items, _newItemsFeature)!;
private IServiceProvidersFeature ServiceProvidersFeature =>
_features.Fetch(ref _features.Cache.ServiceProviders, this, _newServiceProvidersFeature);
_features.Fetch(ref _features.Cache.ServiceProviders, this, _newServiceProvidersFeature)!;
private IHttpAuthenticationFeature HttpAuthenticationFeature =>
_features.Fetch(ref _features.Cache.Authentication, _newHttpAuthenticationFeature);
_features.Fetch(ref _features.Cache.Authentication, _newHttpAuthenticationFeature)!;
private IHttpRequestLifetimeFeature LifetimeFeature =>
_features.Fetch(ref _features.Cache.Lifetime, _newHttpRequestLifetimeFeature);
_features.Fetch(ref _features.Cache.Lifetime, _newHttpRequestLifetimeFeature)!;
private ISessionFeature SessionFeature =>
_features.Fetch(ref _features.Cache.Session, _newSessionFeature);
_features.Fetch(ref _features.Cache.Session, _newSessionFeature)!;
private ISessionFeature SessionFeatureOrNull =>
private ISessionFeature? SessionFeatureOrNull =>
_features.Fetch(ref _features.Cache.Session, _nullSessionFeature);
private IHttpRequestIdentifierFeature RequestIdentifierFeature =>
_features.Fetch(ref _features.Cache.RequestIdentifier, _newHttpRequestIdentifierFeature);
_features.Fetch(ref _features.Cache.RequestIdentifier, _newHttpRequestIdentifierFeature)!;
/// <inheritdoc/>
public override IFeatureCollection Features => _features.Collection ?? ContextDisposed();
@ -156,7 +156,7 @@ namespace Microsoft.AspNetCore.Http
}
/// <inheritdoc/>
public override IDictionary<object, object> Items
public override IDictionary<object, object?> Items
{
get { return ItemsFeature.Items; }
set { ItemsFeature.Items = value; }
@ -221,6 +221,7 @@ namespace Microsoft.AspNetCore.Http
return null;
}
[DoesNotReturn]
private static void ThrowContextDisposed()
{
throw new ObjectDisposedException(nameof(HttpContext), $"Request has finished and {nameof(HttpContext)} disposed.");
@ -228,12 +229,12 @@ namespace Microsoft.AspNetCore.Http
struct FeatureInterfaces
{
public IItemsFeature Items;
public IServiceProvidersFeature ServiceProviders;
public IHttpAuthenticationFeature Authentication;
public IHttpRequestLifetimeFeature Lifetime;
public ISessionFeature Session;
public IHttpRequestIdentifierFeature RequestIdentifier;
public IItemsFeature? Items;
public IServiceProvidersFeature? ServiceProviders;
public IHttpAuthenticationFeature? Authentication;
public IHttpRequestLifetimeFeature? Lifetime;
public ISessionFeature? Session;
public IHttpRequestIdentifierFeature? RequestIdentifier;
}
}
}

View File

@ -7,10 +7,6 @@ namespace Microsoft.AspNetCore.Http.Features.Authentication
{
public class HttpAuthenticationFeature : IHttpAuthenticationFeature
{
public ClaimsPrincipal User
{
get;
set;
}
public ClaimsPrincipal? User { get; set; }
}
}

View File

@ -9,6 +9,6 @@ namespace Microsoft.AspNetCore.Http.Features
/// </summary>
public class DefaultSessionFeature : ISessionFeature
{
public ISession Session { get; set; }
public ISession Session { get; set; } = default!;
}
}

View File

@ -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.IO;
using System.Text;
using System.Threading;
@ -16,8 +17,8 @@ namespace Microsoft.AspNetCore.Http.Features
{
private readonly HttpRequest _request;
private readonly FormOptions _options;
private Task<IFormCollection> _parsedFormTask;
private IFormCollection _form;
private Task<IFormCollection>? _parsedFormTask;
private IFormCollection? _form;
public FormFeature(IFormCollection form)
{
@ -27,7 +28,10 @@ namespace Microsoft.AspNetCore.Http.Features
}
Form = form;
_request = default!;
_options = FormOptions.Default;
}
public FormFeature(HttpRequest request)
: this(request, FormOptions.Default)
{
@ -48,12 +52,11 @@ namespace Microsoft.AspNetCore.Http.Features
_options = options;
}
private MediaTypeHeaderValue ContentType
private MediaTypeHeaderValue? ContentType
{
get
{
MediaTypeHeaderValue mt;
MediaTypeHeaderValue.TryParse(_request.ContentType, out mt);
MediaTypeHeaderValue.TryParse(_request.ContentType, out var mt);
return mt;
}
}
@ -73,7 +76,7 @@ namespace Microsoft.AspNetCore.Http.Features
}
}
public IFormCollection Form
public IFormCollection? Form
{
get { return _form; }
set
@ -138,11 +141,11 @@ namespace Microsoft.AspNetCore.Http.Features
_request.EnableRewind(_options.MemoryBufferThreshold, _options.BufferBodyLengthLimit);
}
FormCollection formFields = null;
FormFileCollection files = null;
FormCollection? formFields = null;
FormFileCollection? files = null;
// Some of these code paths use StreamReader which does not support cancellation tokens.
using (cancellationToken.Register((state) => ((HttpContext)state).Abort(), _request.HttpContext))
using (cancellationToken.Register((state) => ((HttpContext)state!).Abort(), _request.HttpContext))
{
var contentType = ContentType;
// Check the content-type
@ -270,7 +273,7 @@ namespace Microsoft.AspNetCore.Http.Features
return Form;
}
private Encoding FilterEncoding(Encoding encoding)
private static Encoding FilterEncoding(Encoding? encoding)
{
// UTF-7 is insecure and should not be honored. UTF-8 will succeed for most cases.
if (encoding == null || Encoding.UTF7.Equals(encoding))
@ -280,13 +283,13 @@ namespace Microsoft.AspNetCore.Http.Features
return encoding;
}
private bool HasApplicationFormContentType(MediaTypeHeaderValue contentType)
private bool HasApplicationFormContentType([NotNullWhen(true)] MediaTypeHeaderValue? contentType)
{
// Content-Type: application/x-www-form-urlencoded; charset=utf-8
return contentType != null && contentType.MediaType.Equals("application/x-www-form-urlencoded", StringComparison.OrdinalIgnoreCase);
}
private bool HasMultipartFormContentType(MediaTypeHeaderValue contentType)
private bool HasMultipartFormContentType([NotNullWhen(true)] MediaTypeHeaderValue? contentType)
{
// Content-Type: multipart/form-data; boundary=----WebKitFormBoundarymx2fSWqWSd0OxQqq
return contentType != null && contentType.MediaType.Equals("multipart/form-data", StringComparison.OrdinalIgnoreCase);

View File

@ -7,14 +7,14 @@ namespace Microsoft.AspNetCore.Http.Features
{
public class HttpConnectionFeature : IHttpConnectionFeature
{
public string ConnectionId { get; set; }
public string ConnectionId { get; set; } = default!;
public IPAddress LocalIpAddress { get; set; }
public IPAddress? LocalIpAddress { get; set; }
public int LocalPort { get; set; }
public IPAddress RemoteIpAddress { get; set; }
public IPAddress? RemoteIpAddress { get; set; }
public int RemotePort { get; set; }
}
}
}

View File

@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Http.Features
// for a roughly increasing _requestId over restarts
private static long _requestId = DateTime.UtcNow.Ticks;
private string _id = null;
private string? _id = null;
public string TraceIdentifier
{

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNetCore.Http.Features
public int StatusCode { get; set; }
public string ReasonPhrase { get; set; }
public string? ReasonPhrase { get; set; }
public IHeaderDictionary Headers { get; set; }

View File

@ -12,6 +12,6 @@ namespace Microsoft.AspNetCore.Http.Features
Items = new ItemsDictionary();
}
public IDictionary<object, object> Items { get; set; }
public IDictionary<object, object?> Items { get; set; }
}
}

View File

@ -9,12 +9,12 @@ namespace Microsoft.AspNetCore.Http.Features
public class QueryFeature : IQueryFeature
{
// Lambda hoisted to static readonly field to improve inlining https://github.com/dotnet/roslyn/issues/13624
private readonly static Func<IFeatureCollection, IHttpRequestFeature> _nullRequestFeature = f => null;
private readonly static Func<IFeatureCollection, IHttpRequestFeature?> _nullRequestFeature = f => null;
private FeatureReferences<IHttpRequestFeature> _features;
private string _original;
private IQueryCollection _parsedValues;
private string? _original;
private IQueryCollection? _parsedValues;
public QueryFeature(IQueryCollection query)
{
@ -37,7 +37,7 @@ namespace Microsoft.AspNetCore.Http.Features
}
private IHttpRequestFeature HttpRequestFeature =>
_features.Fetch(ref _features.Cache, _nullRequestFeature);
_features.Fetch(ref _features.Cache, _nullRequestFeature)!;
public IQueryCollection Query
{

View File

@ -10,8 +10,8 @@ namespace Microsoft.AspNetCore.Http.Features
{
public class RequestBodyPipeFeature : IRequestBodyPipeFeature
{
private PipeReader _internalPipeReader;
private Stream _streamInstanceWhenWrapped;
private PipeReader? _internalPipeReader;
private Stream? _streamInstanceWhenWrapped;
private HttpContext _context;
public RequestBodyPipeFeature(HttpContext context)

View File

@ -11,11 +11,11 @@ namespace Microsoft.AspNetCore.Http.Features
public class RequestCookiesFeature : IRequestCookiesFeature
{
// Lambda hoisted to static readonly field to improve inlining https://github.com/dotnet/roslyn/issues/13624
private readonly static Func<IFeatureCollection, IHttpRequestFeature> _nullRequestFeature = f => null;
private readonly static Func<IFeatureCollection, IHttpRequestFeature?> _nullRequestFeature = f => null;
private FeatureReferences<IHttpRequestFeature> _features;
private StringValues _original;
private IRequestCookieCollection _parsedValues;
private IRequestCookieCollection? _parsedValues;
public RequestCookiesFeature(IRequestCookieCollection cookies)
{
@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Http.Features
}
private IHttpRequestFeature HttpRequestFeature =>
_features.Fetch(ref _features.Cache, _nullRequestFeature);
_features.Fetch(ref _features.Cache, _nullRequestFeature)!;
public IRequestCookieCollection Cookies
{

View File

@ -9,13 +9,13 @@ namespace Microsoft.AspNetCore.Http.Features
{
public class RequestServicesFeature : IServiceProvidersFeature, IDisposable, IAsyncDisposable
{
private readonly IServiceScopeFactory _scopeFactory;
private IServiceProvider _requestServices;
private IServiceScope _scope;
private readonly IServiceScopeFactory? _scopeFactory;
private IServiceProvider? _requestServices;
private IServiceScope? _scope;
private bool _requestServicesSet;
private readonly HttpContext _context;
public RequestServicesFeature(HttpContext context, IServiceScopeFactory scopeFactory)
public RequestServicesFeature(HttpContext context, IServiceScopeFactory? scopeFactory)
{
_context = context;
_scopeFactory = scopeFactory;
@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Http.Features
_requestServices = _scope.ServiceProvider;
_requestServicesSet = true;
}
return _requestServices;
return _requestServices!;
}
set

View File

@ -13,10 +13,10 @@ namespace Microsoft.AspNetCore.Http.Features
public class ResponseCookiesFeature : IResponseCookiesFeature
{
// Lambda hoisted to static readonly field to improve inlining https://github.com/dotnet/roslyn/issues/13624
private readonly static Func<IFeatureCollection, IHttpResponseFeature> _nullResponseFeature = f => null;
private readonly static Func<IFeatureCollection, IHttpResponseFeature?> _nullResponseFeature = f => null;
private FeatureReferences<IHttpResponseFeature> _features;
private IResponseCookies _cookiesCollection;
private IResponseCookies? _cookiesCollection;
/// <summary>
/// Initializes a new <see cref="ResponseCookiesFeature"/> instance.
@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Http.Features
/// <see cref="IResponseCookiesFeature"/> and the <see cref="IHttpResponseFeature"/>.
/// </param>
/// <param name="builderPool">The <see cref="ObjectPool{T}"/>, if available.</param>
public ResponseCookiesFeature(IFeatureCollection features, ObjectPool<StringBuilder> builderPool)
public ResponseCookiesFeature(IFeatureCollection features, ObjectPool<StringBuilder>? builderPool)
{
if (features == null)
{
@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Http.Features
_features.Initalize(features);
}
private IHttpResponseFeature HttpResponseFeature => _features.Fetch(ref _features.Cache, _nullResponseFeature);
private IHttpResponseFeature HttpResponseFeature => _features.Fetch(ref _features.Cache, _nullResponseFeature)!;
/// <inheritdoc />
public IResponseCookies Cookies
@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.Http.Features
if (_cookiesCollection == null)
{
var headers = HttpResponseFeature.Headers;
_cookiesCollection = new ResponseCookies(headers, null);
_cookiesCollection = new ResponseCookies(headers);
}
return _cookiesCollection;

View File

@ -1,4 +1,4 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.AspNetCore.Routing;
@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Http.Features
/// </summary>
public class RouteValuesFeature : IRouteValuesFeature
{
private RouteValueDictionary _routeValues;
private RouteValueDictionary? _routeValues;
/// <summary>
/// Gets or sets the <see cref="RouteValueDictionary"/> associated with the currrent
@ -31,4 +31,4 @@ namespace Microsoft.AspNetCore.Http.Features
set => _routeValues = value;
}
}
}
}

View File

@ -7,6 +7,6 @@ namespace Microsoft.AspNetCore.Http.Features
{
public class ServiceProvidersFeature : IServiceProvidersFeature
{
public IServiceProvider RequestServices { get; set; }
public IServiceProvider RequestServices { get; set; } = default!;
}
}
}

View File

@ -9,11 +9,11 @@ namespace Microsoft.AspNetCore.Http.Features
{
public class TlsConnectionFeature : ITlsConnectionFeature
{
public X509Certificate2 ClientCertificate { get; set; }
public X509Certificate2? ClientCertificate { get; set; }
public Task<X509Certificate2> GetClientCertificateAsync(CancellationToken cancellationToken)
public Task<X509Certificate2?> GetClientCertificateAsync(CancellationToken cancellationToken)
{
return Task.FromResult(ClientCertificate);
}
}
}
}

View File

@ -23,14 +23,14 @@ namespace Microsoft.AspNetCore.Http
private static IFormFileCollection EmptyFiles = new FormFileCollection();
private IFormFileCollection _files;
private IFormFileCollection? _files;
private FormCollection()
{
// For static Empty
}
public FormCollection(Dictionary<string, StringValues> fields, IFormFileCollection files = null)
public FormCollection(Dictionary<string, StringValues>? fields, IFormFileCollection? files = null)
{
// can be null
Store = fields;
@ -46,7 +46,7 @@ namespace Microsoft.AspNetCore.Http
private set { _files = value; }
}
private Dictionary<string, StringValues> Store { get; set; }
private Dictionary<string, StringValues>? Store { get; set; }
/// <summary>
/// Get or sets the associated value from the collection as a single string.

View File

@ -50,7 +50,7 @@ namespace Microsoft.AspNetCore.Http
/// <summary>
/// Gets the header dictionary of the uploaded file.
/// </summary>
public IHeaderDictionary Headers { get; set; }
public IHeaderDictionary Headers { get; set; } = default!;
/// <summary>
/// Gets the file length in bytes.

View File

@ -12,10 +12,10 @@ namespace Microsoft.AspNetCore.Http
public class FormFileCollection : List<IFormFile>, IFormFileCollection
{
/// <inheritdoc />
public IFormFile this[string name] => GetFile(name);
public IFormFile? this[string name] => GetFile(name);
/// <inheritdoc />
public IFormFile GetFile(string name)
public IFormFile? GetFile(string name)
{
foreach (var file in this)
{

View File

@ -4,6 +4,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Extensions.Primitives;
using Microsoft.Net.Http.Headers;
@ -25,7 +26,7 @@ namespace Microsoft.AspNetCore.Http
{
}
public HeaderDictionary(Dictionary<string, StringValues> store)
public HeaderDictionary(Dictionary<string, StringValues>? store)
{
Store = store;
}
@ -35,8 +36,9 @@ namespace Microsoft.AspNetCore.Http
EnsureStore(capacity);
}
private Dictionary<string, StringValues> Store { get; set; }
private Dictionary<string, StringValues>? Store { get; set; }
[MemberNotNull(nameof(Store))]
private void EnsureStore(int capacity)
{
if (Store == null)
@ -93,7 +95,7 @@ namespace Microsoft.AspNetCore.Http
/// <returns></returns>
StringValues IDictionary<string, StringValues>.this[string key]
{
get { return Store[key]; }
get { return this[key]; }
set
{
ThrowIfReadOnly();

View File

@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Http
private static AsyncLocal<HttpContextHolder> _httpContextCurrent = new AsyncLocal<HttpContextHolder>();
/// <inheritdoc/>
public HttpContext HttpContext
public HttpContext? HttpContext
{
get
{
@ -39,7 +39,7 @@ namespace Microsoft.AspNetCore.Http
private class HttpContextHolder
{
public HttpContext Context;
public HttpContext? Context;
}
}
}

View File

@ -14,7 +14,7 @@ namespace Microsoft.AspNetCore.Http
[Obsolete("This is obsolete and will be removed in a future version. Use DefaultHttpContextFactory instead.")]
public class HttpContextFactory : IHttpContextFactory
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IHttpContextAccessor? _httpContextAccessor;
private readonly FormOptions _formOptions;
private readonly IServiceScopeFactory _serviceScopeFactory;
@ -23,7 +23,7 @@ namespace Microsoft.AspNetCore.Http
/// </summary>
/// <param name="formOptions">Options to set when instantianting the HTTP context object.</param>
public HttpContextFactory(IOptions<FormOptions> formOptions)
: this(formOptions, serviceScopeFactory: null)
: this(formOptions, serviceScopeFactory: null!)
{
}
@ -42,8 +42,8 @@ namespace Microsoft.AspNetCore.Http
/// </summary>
/// <param name="formOptions">Options to set when instantianting the HTTP context object.</param>
/// <param name="httpContextAccessor">Object to be used to access the HTTP context instance.</param>
public HttpContextFactory(IOptions<FormOptions> formOptions, IHttpContextAccessor httpContextAccessor)
: this(formOptions, serviceScopeFactory: null, httpContextAccessor: httpContextAccessor)
public HttpContextFactory(IOptions<FormOptions> formOptions, IHttpContextAccessor? httpContextAccessor)
: this(formOptions, serviceScopeFactory: null!, httpContextAccessor: httpContextAccessor)
{
}
@ -53,7 +53,7 @@ namespace Microsoft.AspNetCore.Http
/// <param name="formOptions">Options to set when instantianting the HTTP context object.</param>
/// <param name="serviceScopeFactory">Factory object used to create the service scope for the HTTP context.</param>
/// <param name="httpContextAccessor">Options to set when instantianting the Default HTTP context object.</param>
public HttpContextFactory(IOptions<FormOptions> formOptions, IServiceScopeFactory serviceScopeFactory, IHttpContextAccessor httpContextAccessor)
public HttpContextFactory(IOptions<FormOptions> formOptions, IServiceScopeFactory serviceScopeFactory, IHttpContextAccessor? httpContextAccessor)
{
if (formOptions == null)
{

View File

@ -39,10 +39,10 @@ namespace Microsoft.AspNetCore.Http
}
private IHttpConnectionFeature HttpConnectionFeature =>
_features.Fetch(ref _features.Cache.Connection, _newHttpConnectionFeature);
_features.Fetch(ref _features.Cache.Connection, _newHttpConnectionFeature)!;
private ITlsConnectionFeature TlsConnectionFeature=>
_features.Fetch(ref _features.Cache.TlsConnection, _newTlsConnectionFeature);
_features.Fetch(ref _features.Cache.TlsConnection, _newTlsConnectionFeature)!;
/// <inheritdoc />
public override string Id
@ -51,7 +51,7 @@ namespace Microsoft.AspNetCore.Http
set { HttpConnectionFeature.ConnectionId = value; }
}
public override IPAddress RemoteIpAddress
public override IPAddress? RemoteIpAddress
{
get { return HttpConnectionFeature.RemoteIpAddress; }
set { HttpConnectionFeature.RemoteIpAddress = value; }
@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Http
set { HttpConnectionFeature.RemotePort = value; }
}
public override IPAddress LocalIpAddress
public override IPAddress? LocalIpAddress
{
get { return HttpConnectionFeature.LocalIpAddress; }
set { HttpConnectionFeature.LocalIpAddress = value; }
@ -75,21 +75,21 @@ namespace Microsoft.AspNetCore.Http
set { HttpConnectionFeature.LocalPort = value; }
}
public override X509Certificate2 ClientCertificate
public override X509Certificate2? ClientCertificate
{
get { return TlsConnectionFeature.ClientCertificate; }
set { TlsConnectionFeature.ClientCertificate = value; }
}
public override Task<X509Certificate2> GetClientCertificateAsync(CancellationToken cancellationToken = default)
public override Task<X509Certificate2?> GetClientCertificateAsync(CancellationToken cancellationToken = default)
{
return TlsConnectionFeature.GetClientCertificateAsync(cancellationToken);
}
struct FeatureInterfaces
{
public IHttpConnectionFeature Connection;
public ITlsConnectionFeature TlsConnection;
public IHttpConnectionFeature? Connection;
public ITlsConnectionFeature? TlsConnection;
}
}
}

View File

@ -18,8 +18,8 @@ namespace Microsoft.AspNetCore.Http
private const string Https = "https";
// Lambdas hoisted to static readonly fields to improve inlining https://github.com/dotnet/roslyn/issues/13624
private readonly static Func<IFeatureCollection, IHttpRequestFeature> _nullRequestFeature = f => null;
private readonly static Func<IFeatureCollection, IQueryFeature> _newQueryFeature = f => new QueryFeature(f);
private readonly static Func<IFeatureCollection, IHttpRequestFeature?> _nullRequestFeature = f => null;
private readonly static Func<IFeatureCollection, IQueryFeature?> _newQueryFeature = f => new QueryFeature(f);
private readonly static Func<DefaultHttpRequest, IFormFeature> _newFormFeature = r => new FormFeature(r, r._context.FormOptions ?? FormOptions.Default);
private readonly static Func<IFeatureCollection, IRequestCookiesFeature> _newRequestCookiesFeature = f => new RequestCookiesFeature(f);
private readonly static Func<IFeatureCollection, IRouteValuesFeature> _newRouteValuesFeature = f => new RouteValuesFeature();
@ -52,39 +52,39 @@ namespace Microsoft.AspNetCore.Http
public override HttpContext HttpContext => _context;
private IHttpRequestFeature HttpRequestFeature =>
_features.Fetch(ref _features.Cache.Request, _nullRequestFeature);
_features.Fetch(ref _features.Cache.Request, _nullRequestFeature)!;
private IQueryFeature QueryFeature =>
_features.Fetch(ref _features.Cache.Query, _newQueryFeature);
_features.Fetch(ref _features.Cache.Query, _newQueryFeature)!;
private IFormFeature FormFeature =>
_features.Fetch(ref _features.Cache.Form, this, _newFormFeature);
_features.Fetch(ref _features.Cache.Form, this, _newFormFeature)!;
private IRequestCookiesFeature RequestCookiesFeature =>
_features.Fetch(ref _features.Cache.Cookies, _newRequestCookiesFeature);
_features.Fetch(ref _features.Cache.Cookies, _newRequestCookiesFeature)!;
private IRouteValuesFeature RouteValuesFeature =>
_features.Fetch(ref _features.Cache.RouteValues, _newRouteValuesFeature);
_features.Fetch(ref _features.Cache.RouteValues, _newRouteValuesFeature)!;
private IRequestBodyPipeFeature RequestBodyPipeFeature =>
_features.Fetch(ref _features.Cache.BodyPipe, this.HttpContext, _newRequestBodyPipeFeature);
_features.Fetch(ref _features.Cache.BodyPipe, this.HttpContext, _newRequestBodyPipeFeature)!;
public override PathString PathBase
{
get { return new PathString(HttpRequestFeature.PathBase); }
set { HttpRequestFeature.PathBase = value.Value; }
set { HttpRequestFeature.PathBase = value.Value ?? string.Empty; }
}
public override PathString Path
{
get { return new PathString(HttpRequestFeature.Path); }
set { HttpRequestFeature.Path = value.Value; }
set { HttpRequestFeature.Path = value.Value ?? string.Empty; }
}
public override QueryString QueryString
{
get { return new QueryString(HttpRequestFeature.QueryString); }
set { HttpRequestFeature.QueryString = value.Value; }
set { HttpRequestFeature.QueryString = value.Value ?? string.Empty; }
}
public override long? ContentLength
@ -181,12 +181,12 @@ namespace Microsoft.AspNetCore.Http
struct FeatureInterfaces
{
public IHttpRequestFeature Request;
public IQueryFeature Query;
public IFormFeature Form;
public IRequestCookiesFeature Cookies;
public IRouteValuesFeature RouteValues;
public IRequestBodyPipeFeature BodyPipe;
public IHttpRequestFeature? Request;
public IQueryFeature? Query;
public IFormFeature? Form;
public IRequestCookiesFeature? Cookies;
public IRouteValuesFeature? RouteValues;
public IRequestBodyPipeFeature? BodyPipe;
}
}
}

View File

@ -14,9 +14,9 @@ namespace Microsoft.AspNetCore.Http
internal sealed class DefaultHttpResponse : HttpResponse
{
// Lambdas hoisted to static readonly fields to improve inlining https://github.com/dotnet/roslyn/issues/13624
private readonly static Func<IFeatureCollection, IHttpResponseFeature> _nullResponseFeature = f => null;
private readonly static Func<IFeatureCollection, IHttpResponseBodyFeature> _nullResponseBodyFeature = f => null;
private readonly static Func<IFeatureCollection, IResponseCookiesFeature> _newResponseCookiesFeature = f => new ResponseCookiesFeature(f);
private readonly static Func<IFeatureCollection, IHttpResponseFeature?> _nullResponseFeature = f => null;
private readonly static Func<IFeatureCollection, IHttpResponseBodyFeature?> _nullResponseBodyFeature = f => null;
private readonly static Func<IFeatureCollection, IResponseCookiesFeature?> _newResponseCookiesFeature = f => new ResponseCookiesFeature(f);
private readonly DefaultHttpContext _context;
private FeatureReferences<FeatureInterfaces> _features;
@ -43,13 +43,13 @@ namespace Microsoft.AspNetCore.Http
}
private IHttpResponseFeature HttpResponseFeature =>
_features.Fetch(ref _features.Cache.Response, _nullResponseFeature);
_features.Fetch(ref _features.Cache.Response, _nullResponseFeature)!;
private IHttpResponseBodyFeature HttpResponseBodyFeature =>
_features.Fetch(ref _features.Cache.ResponseBody, _nullResponseBodyFeature);
_features.Fetch(ref _features.Cache.ResponseBody, _nullResponseBodyFeature)!;
private IResponseCookiesFeature ResponseCookiesFeature =>
_features.Fetch(ref _features.Cache.Cookies, _newResponseCookiesFeature);
_features.Fetch(ref _features.Cache.Cookies, _newResponseCookiesFeature)!;
public override HttpContext HttpContext { get { return _context; } }
@ -176,9 +176,9 @@ namespace Microsoft.AspNetCore.Http
struct FeatureInterfaces
{
public IHttpResponseFeature Response;
public IHttpResponseBodyFeature ResponseBody;
public IResponseCookiesFeature Cookies;
public IHttpResponseFeature? Response;
public IHttpResponseBodyFeature? ResponseBody;
public IResponseCookiesFeature? Cookies;
}
}
}

View File

@ -13,8 +13,8 @@ namespace Microsoft.AspNetCore.Http
internal sealed class DefaultWebSocketManager : WebSocketManager
{
// Lambdas hoisted to static readonly fields to improve inlining https://github.com/dotnet/roslyn/issues/13624
private readonly static Func<IFeatureCollection, IHttpRequestFeature> _nullRequestFeature = f => null;
private readonly static Func<IFeatureCollection, IHttpWebSocketFeature> _nullWebSocketFeature = f => null;
private readonly static Func<IFeatureCollection, IHttpRequestFeature?> _nullRequestFeature = f => null;
private readonly static Func<IFeatureCollection, IHttpWebSocketFeature?> _nullWebSocketFeature = f => null;
private FeatureReferences<FeatureInterfaces> _features;
@ -39,10 +39,10 @@ namespace Microsoft.AspNetCore.Http
}
private IHttpRequestFeature HttpRequestFeature =>
_features.Fetch(ref _features.Cache.Request, _nullRequestFeature);
_features.Fetch(ref _features.Cache.Request, _nullRequestFeature)!;
private IHttpWebSocketFeature WebSocketFeature =>
_features.Fetch(ref _features.Cache.WebSockets, _nullWebSocketFeature);
_features.Fetch(ref _features.Cache.WebSockets, _nullWebSocketFeature)!;
public override bool IsWebSocketRequest
{
@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.Http
}
}
public override Task<WebSocket> AcceptWebSocketAsync(string subProtocol)
public override Task<WebSocket> AcceptWebSocketAsync(string? subProtocol)
{
if (WebSocketFeature == null)
{
@ -71,8 +71,8 @@ namespace Microsoft.AspNetCore.Http
struct FeatureInterfaces
{
public IHttpRequestFeature Request;
public IHttpWebSocketFeature WebSockets;
public IHttpRequestFeature? Request;
public IHttpWebSocketFeature? WebSockets;
}
}
}

View File

@ -3,25 +3,26 @@
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.AspNetCore.Http
{
internal class ItemsDictionary : IDictionary<object, object>
internal class ItemsDictionary : IDictionary<object, object?>
{
private IDictionary<object, object> _items;
private IDictionary<object, object?>? _items;
public ItemsDictionary()
{}
public ItemsDictionary(IDictionary<object, object> items)
public ItemsDictionary(IDictionary<object, object?> items)
{
_items = items;
}
public IDictionary<object, object> Items => this;
public IDictionary<object, object?> Items => this;
// Replace the indexer with one that returns null for missing values
object IDictionary<object, object>.this[object key]
object? IDictionary<object, object?>.this[object key]
{
get
{
@ -38,16 +39,16 @@ namespace Microsoft.AspNetCore.Http
}
}
void IDictionary<object, object>.Add(object key, object value)
void IDictionary<object, object?>.Add(object key, object? value)
{
EnsureDictionary();
_items.Add(key, value);
}
bool IDictionary<object, object>.ContainsKey(object key)
bool IDictionary<object, object?>.ContainsKey(object key)
=> _items != null && _items.ContainsKey(key);
ICollection<object> IDictionary<object, object>.Keys
ICollection<object> IDictionary<object, object?>.Keys
{
get
{
@ -60,16 +61,16 @@ namespace Microsoft.AspNetCore.Http
}
}
bool IDictionary<object, object>.Remove(object key)
bool IDictionary<object, object?>.Remove(object key)
=> _items != null && _items.Remove(key);
bool IDictionary<object, object>.TryGetValue(object key, out object value)
bool IDictionary<object, object?>.TryGetValue(object key, out object? value)
{
value = null;
return _items != null && _items.TryGetValue(key, out value);
}
ICollection<object> IDictionary<object, object>.Values
ICollection<object?> IDictionary<object, object?>.Values
{
get
{
@ -82,18 +83,18 @@ namespace Microsoft.AspNetCore.Http
}
}
void ICollection<KeyValuePair<object, object>>.Add(KeyValuePair<object, object> item)
void ICollection<KeyValuePair<object, object?>>.Add(KeyValuePair<object, object?> item)
{
EnsureDictionary();
_items.Add(item);
}
void ICollection<KeyValuePair<object, object>>.Clear() => _items?.Clear();
void ICollection<KeyValuePair<object, object?>>.Clear() => _items?.Clear();
bool ICollection<KeyValuePair<object, object>>.Contains(KeyValuePair<object, object> item)
bool ICollection<KeyValuePair<object, object?>>.Contains(KeyValuePair<object, object?> item)
=> _items != null && _items.Contains(item);
void ICollection<KeyValuePair<object, object>>.CopyTo(KeyValuePair<object, object>[] array, int arrayIndex)
void ICollection<KeyValuePair<object, object?>>.CopyTo(KeyValuePair<object, object?>[] array, int arrayIndex)
{
if (_items == null)
{
@ -104,11 +105,11 @@ namespace Microsoft.AspNetCore.Http
_items?.CopyTo(array, arrayIndex);
}
int ICollection<KeyValuePair<object, object>>.Count => _items?.Count ?? 0;
int ICollection<KeyValuePair<object, object?>>.Count => _items?.Count ?? 0;
bool ICollection<KeyValuePair<object, object>>.IsReadOnly => _items?.IsReadOnly ?? false;
bool ICollection<KeyValuePair<object, object?>>.IsReadOnly => _items?.IsReadOnly ?? false;
bool ICollection<KeyValuePair<object, object>>.Remove(KeyValuePair<object, object> item)
bool ICollection<KeyValuePair<object, object?>>.Remove(KeyValuePair<object, object?> item)
{
if (_items == null)
{
@ -122,26 +123,27 @@ namespace Microsoft.AspNetCore.Http
return false;
}
[MemberNotNull(nameof(_items))]
private void EnsureDictionary()
{
if (_items == null)
{
_items = new Dictionary<object, object>();
_items = new Dictionary<object, object?>();
}
}
IEnumerator<KeyValuePair<object, object>> IEnumerable<KeyValuePair<object, object>>.GetEnumerator()
IEnumerator<KeyValuePair<object, object?>> IEnumerable<KeyValuePair<object, object?>>.GetEnumerator()
=> _items?.GetEnumerator() ?? EmptyEnumerator.Instance;
IEnumerator IEnumerable.GetEnumerator() => _items?.GetEnumerator() ?? EmptyEnumerator.Instance;
private class EmptyEnumerator : IEnumerator<KeyValuePair<object, object>>
private class EmptyEnumerator : IEnumerator<KeyValuePair<object, object?>>
{
// In own class so only initalized if GetEnumerator is called on an empty ItemsDictionary
public readonly static IEnumerator<KeyValuePair<object, object>> Instance = new EmptyEnumerator();
public KeyValuePair<object, object> Current => default;
public readonly static IEnumerator<KeyValuePair<object, object?>> Instance = new EmptyEnumerator();
public KeyValuePair<object, object?> Current => default;
object IEnumerator.Current => null;
object? IEnumerator.Current => null;
public void Dispose()
{ }
@ -155,8 +157,8 @@ namespace Microsoft.AspNetCore.Http
private static class EmptyDictionary
{
// In own class so only initalized if CopyTo is called on an empty ItemsDictionary
public readonly static IDictionary<object, object> Dictionary = new Dictionary<object, object>();
public static ICollection<KeyValuePair<object, object>> Collection => Dictionary;
public readonly static IDictionary<object, object?> Dictionary = new Dictionary<object, object?>();
public static ICollection<KeyValuePair<object, object?>> Collection => Dictionary;
}
}
}

View File

@ -4,6 +4,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Net.Http.Headers;
namespace Microsoft.AspNetCore.Http
@ -17,7 +18,7 @@ namespace Microsoft.AspNetCore.Http
private static readonly IEnumerator<KeyValuePair<string, string>> EmptyIEnumeratorType = EmptyEnumerator;
private static readonly IEnumerator EmptyIEnumerator = EmptyEnumerator;
private Dictionary<string, string> Store { get; set; }
private Dictionary<string, string>? Store { get; set; }
public RequestCookieCollection()
{
@ -33,7 +34,7 @@ namespace Microsoft.AspNetCore.Http
Store = new Dictionary<string, string>(capacity, StringComparer.OrdinalIgnoreCase);
}
public string this[string key]
public string? this[string key]
{
get
{
@ -47,8 +48,7 @@ namespace Microsoft.AspNetCore.Http
return null;
}
string value;
if (TryGetValue(key, out value))
if (TryGetValue(key, out var value))
{
return value;
}
@ -63,8 +63,7 @@ namespace Microsoft.AspNetCore.Http
return Empty;
}
IList<CookieHeaderValue> cookies;
if (CookieHeaderValue.TryParseList(values, out cookies))
if (CookieHeaderValue.TryParseList(values, out var cookies))
{
if (cookies.Count == 0)
{
@ -72,7 +71,7 @@ namespace Microsoft.AspNetCore.Http
}
var collection = new RequestCookieCollection(cookies.Count);
var store = collection.Store;
var store = collection.Store!;
for (var i = 0; i < cookies.Count; i++)
{
var cookie = cookies[i];
@ -119,7 +118,7 @@ namespace Microsoft.AspNetCore.Http
return Store.ContainsKey(key);
}
public bool TryGetValue(string key, out string value)
public bool TryGetValue(string key, [MaybeNullWhen(false)] out string? value)
{
if (Store == null)
{

View File

@ -3,8 +3,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Extensions.ObjectPool;
using Microsoft.Extensions.Primitives;
using Microsoft.Net.Http.Headers;
@ -19,8 +17,7 @@ namespace Microsoft.AspNetCore.Http
/// Create a new wrapper.
/// </summary>
/// <param name="headers">The <see cref="IHeaderDictionary"/> for the response.</param>
/// <param name="builderPool">The <see cref="ObjectPool{T}"/>, if available.</param>
public ResponseCookies(IHeaderDictionary headers, ObjectPool<StringBuilder> builderPool)
public ResponseCookies(IHeaderDictionary headers)
{
if (headers == null)
{

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Description>ASP.NET Core default HTTP feature implementations.</Description>
@ -9,6 +9,8 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>aspnetcore</PackageTags>
<IsPackable>false</IsPackable>
<Nullable>enable</Nullable>
<LangVersion>preview</LangVersion>
</PropertyGroup>
<ItemGroup>

View File

@ -1,11 +1,7 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
namespace Microsoft.AspNetCore.Http
@ -22,7 +18,7 @@ namespace Microsoft.AspNetCore.Http
_serviceProvider = serviceProvider;
}
public IMiddleware Create(Type middlewareType)
public IMiddleware? Create(Type middlewareType)
{
return _serviceProvider.GetRequiredService(middlewareType) as IMiddleware;
}

View File

@ -21,7 +21,7 @@ namespace Microsoft.AspNetCore.Http
private static readonly IEnumerator<KeyValuePair<string, StringValues>> EmptyIEnumeratorType = EmptyEnumerator;
private static readonly IEnumerator EmptyIEnumerator = EmptyEnumerator;
private Dictionary<string, StringValues> Store { get; set; }
private Dictionary<string, StringValues>? Store { get; set; }
public QueryCollection()
{

View File

@ -15,7 +15,7 @@ namespace Microsoft.AspNetCore.Http
/// </summary>
public class StreamResponseBodyFeature : IHttpResponseBodyFeature
{
private PipeWriter _pipeWriter;
private PipeWriter? _pipeWriter;
private bool _started;
private bool _completed;
private bool _disposed;
@ -48,7 +48,7 @@ namespace Microsoft.AspNetCore.Http
/// <summary>
/// The prior feature, if any.
/// </summary>
public IHttpResponseBodyFeature PriorFeature { get; }
public IHttpResponseBodyFeature? PriorFeature { get; }
/// <summary>
/// A PipeWriter adapted over the given stream.

View File

@ -13,7 +13,7 @@ namespace Microsoft.AspNetCore.Http.Tests
public void DeleteCookieShouldSetDefaultPath()
{
var headers = new HeaderDictionary();
var cookies = new ResponseCookies(headers, null);
var cookies = new ResponseCookies(headers);
var testCookie = "TestCookie";
cookies.Delete(testCookie);
@ -29,7 +29,7 @@ namespace Microsoft.AspNetCore.Http.Tests
public void DeleteCookieWithCookieOptionsShouldKeepPropertiesOfCookieOptions()
{
var headers = new HeaderDictionary();
var cookies = new ResponseCookies(headers, null);
var cookies = new ResponseCookies(headers);
var testCookie = "TestCookie";
var time = new DateTimeOffset(2000, 1, 1, 1, 1, 1, 1, TimeSpan.Zero);
var options = new CookieOptions
@ -58,7 +58,7 @@ namespace Microsoft.AspNetCore.Http.Tests
public void NoParamsDeleteRemovesCookieCreatedByAdd()
{
var headers = new HeaderDictionary();
var cookies = new ResponseCookies(headers, null);
var cookies = new ResponseCookies(headers);
var testCookie = "TestCookie";
cookies.Append(testCookie, testCookie);
@ -75,7 +75,7 @@ namespace Microsoft.AspNetCore.Http.Tests
public void ProvidesMaxAgeWithCookieOptionsArgumentExpectMaxAgeToBeSet()
{
var headers = new HeaderDictionary();
var cookies = new ResponseCookies(headers, null);
var cookies = new ResponseCookies(headers);
var cookieOptions = new CookieOptions();
var maxAgeTime = TimeSpan.FromHours(1);
cookieOptions.MaxAge = TimeSpan.FromHours(1);
@ -111,7 +111,7 @@ namespace Microsoft.AspNetCore.Http.Tests
string expected)
{
var headers = new HeaderDictionary();
var cookies = new ResponseCookies(headers, null);
var cookies = new ResponseCookies(headers);
cookies.Append(key, value);

View File

@ -204,7 +204,7 @@ namespace Microsoft.AspNetCore.WebUtilities
{
public MultipartSection() { }
public long? BaseStreamOffset { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public System.IO.Stream? Body { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public System.IO.Stream Body { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }
public string? ContentDisposition { get { throw null; } }
public string? ContentType { get { throw null; } }
public System.Collections.Generic.Dictionary<string, Microsoft.Extensions.Primitives.StringValues>? Headers { [System.Runtime.CompilerServices.CompilerGeneratedAttribute] get { throw null; } [System.Runtime.CompilerServices.CompilerGeneratedAttribute] set { } }

View File

@ -36,7 +36,10 @@ namespace Microsoft.AspNetCore.WebUtilities
public Dictionary<string, StringValues>? Headers { get; set; }
public Stream? Body { get; set; }
/// <summary>
/// Gets or sets the body.
/// </summary>
public Stream Body { get; set; } = default!;
/// <summary>
/// The position where the body starts in the total multipart body.

View File

@ -1,17 +1,19 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.Extensions.Internal
{
internal class CopyOnWriteDictionary<TKey, TValue> : IDictionary<TKey, TValue>
internal class CopyOnWriteDictionary<TKey, TValue> : IDictionary<TKey, TValue> where TKey : notnull
{
private readonly IDictionary<TKey, TValue> _sourceDictionary;
private readonly IEqualityComparer<TKey> _comparer;
private IDictionary<TKey, TValue> _innerDictionary;
private IDictionary<TKey, TValue>? _innerDictionary;
public CopyOnWriteDictionary(
IDictionary<TKey, TValue> sourceDictionary,
@ -112,7 +114,7 @@ namespace Microsoft.Extensions.Internal
return WriteDictionary.Remove(key);
}
public virtual bool TryGetValue(TKey key, out TValue value)
public virtual bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
{
return ReadDictionary.TryGetValue(key, out value);
}
@ -152,4 +154,4 @@ namespace Microsoft.Extensions.Internal
return GetEnumerator();
}
}
}
}

View File

@ -1,15 +1,18 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
namespace Microsoft.Extensions.Internal
{
internal struct CopyOnWriteDictionaryHolder<TKey, TValue>
internal struct CopyOnWriteDictionaryHolder<TKey, TValue> where TKey : notnull
{
private readonly Dictionary<TKey, TValue> _source;
private Dictionary<TKey, TValue> _copy;
private Dictionary<TKey, TValue>? _copy;
public CopyOnWriteDictionaryHolder(Dictionary<TKey, TValue> source)
{
@ -128,7 +131,7 @@ namespace Microsoft.Extensions.Internal
return WriteDictionary.Remove(key);
}
public bool TryGetValue(TKey key, out TValue value)
public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value)
{
return ReadDictionary.TryGetValue(key, out value);
}