-
Notifications
You must be signed in to change notification settings - Fork 10.4k
Add nullability to remaining middleware #26098
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@@ -43,7 +44,7 @@ public interface ISession | |||
/// <param name="key"></param> | |||
/// <param name="value"></param> | |||
/// <returns></returns> | |||
bool TryGetValue(string key, out byte[] value); | |||
bool TryGetValue(string key, [MaybeNullWhen(false)] out byte[] value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll see if I can port this change to 5.0. It is more restrictive so we might as well try and get it right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally we would have:
bool TryGetValue(string key, [MaybeNullWhen(false)] out byte[] value); | |
bool TryGetValue(string key, [NotNullWhen(true)] out byte[]? value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be more problematic with how distributed session works. I think it can return null while returning true.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be more problematic with how distributed session works. I think it can return null while returning true.
I wouldn't expect that. Where do you see it happening?
@@ -29,7 +29,7 @@ internal static bool IsGetOrHeadMethod(string method) | |||
|
|||
internal static bool PathEndsInSlash(PathString path) | |||
{ | |||
return path.Value.EndsWith("/", StringComparison.Ordinal); | |||
return path.HasValue && path.Value!.EndsWith("/", StringComparison.Ordinal); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a bug. PathSting.HasValue
is annotated with MemberNotNullWhen
but it doesn't work here. @sharwell any idea why that might?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -11,6 +11,11 @@ public static class WebSocketsDependencyInjectionExtensions | |||
{ | |||
public static IServiceCollection AddWebSockets(this IServiceCollection services, Action<WebSocketOptions> configure) | |||
{ | |||
if (configure is null) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
services.Configure
will throw if configure
is null. Might as well throw it here and make it consistent with all of our other extension methods.
@@ -108,7 +108,7 @@ public async Task Invoke(HttpContext context) | |||
} | |||
finally | |||
{ | |||
context.Features.Set<ISessionFeature>(null); | |||
context.Features.Set<ISessionFeature?>(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❔ Can you link me to the definition of Set<T>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aspnetcore/src/Http/Http.Features/src/FeatureCollection.cs
Lines 101 to 104 in 15f341f
public void Set<TFeature>(TFeature instance) | |
{ | |
this[typeof(TFeature)] = instance; | |
} |
@@ -8,6 +8,6 @@ namespace Microsoft.AspNetCore.Session | |||
{ | |||
public class SessionFeature : ISessionFeature | |||
{ | |||
public ISession Session { get; set; } | |||
public ISession Session { get; set; } = default!; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Consider using this instead:
public ISession Session { get; set; } = default!; | |
[DisallowNull] | |
public ISession? Session { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ooh, what does this do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I don't think this works for this case. In the ordinary case, features are instantiated by the framework and initialize these properties. If the feature exists, user code does not see a null value. Ideally we would have created initialized this in the ctor, but that ship has sailed.
src/Middleware/ResponseCompression/src/ResponseCompressionBody.cs
Outdated
Show resolved
Hide resolved
@@ -105,7 +106,7 @@ private byte[] IdBytes | |||
_sessionIdBytes = new byte[IdByteCount]; | |||
RandomNumberGenerator.Fill(_sessionIdBytes); | |||
} | |||
return _sessionIdBytes; | |||
return _sessionIdBytes!; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:\ Not a huge fan of this suppression, but I'm not exactly sure what the alternative would be. You could put MemberNotNullWhen
on the IsAvailable
property and mark this property as nullable, but I'm not sure it's an improvement over what you have here. Here are all the potential options I see:
- Applying
MemberNotNullWhen
toIsAvailable
- Changing the property type to
byte[]?
- Returning
_sessionIdBytes ?? Array.Empty<byte>()
- Returning
_sessionIdBytes ?? throw new InvalidOperationException(...)
- Keeping the suppression
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Tratcher thoughts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code could be restructured. Load always sets _sessionIdBytes or _sessionId so if IdBytes is called then it will return a non-null value. How about just removing the IsAvailable check here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. I've removed the check here. I've added a new exception to Serialize
which would have previously resulted in a null-ref.
@@ -43,7 +44,7 @@ public interface ISession | |||
/// <param name="key"></param> | |||
/// <param name="value"></param> | |||
/// <returns></returns> | |||
bool TryGetValue(string key, out byte[] value); | |||
bool TryGetValue(string key, [MaybeNullWhen(false)] out byte[] value); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be more problematic with how distributed session works. I think it can return null while returning true.
I wouldn't expect that. Where do you see it happening?
81d7628
to
b1b301c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🆙 📅
@@ -105,7 +106,7 @@ private byte[] IdBytes | |||
_sessionIdBytes = new byte[IdByteCount]; | |||
RandomNumberGenerator.Fill(_sessionIdBytes); | |||
} | |||
return _sessionIdBytes; | |||
return _sessionIdBytes!; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. I've removed the check here. I've added a new exception to Serialize
which would have previously resulted in a null-ref.
@@ -8,6 +8,6 @@ namespace Microsoft.AspNetCore.Session | |||
{ | |||
public class SessionFeature : ISessionFeature | |||
{ | |||
public ISession Session { get; set; } | |||
public ISession Session { get; set; } = default!; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I don't think this works for this case. In the ordinary case, features are instantiated by the framework and initialize these properties. If the feature exists, user code does not see a null value. Ideally we would have created initialized this in the ctor, but that ship has sailed.
e4923e8
to
f99b482
Compare
Adds nullable annotations to the remaining middleware in the repo (except SpaServices)