Background and Motivation
RequestDelegate can be used with methods/lambdas that return a value that is then ignored.
Delegate signature:
|
/// <summary> |
|
/// A function that can process an HTTP request. |
|
/// </summary> |
|
/// <param name="context">The <see cref="HttpContext"/> for the request.</param> |
|
/// <returns>A task that represents the completion of request processing.</returns> |
|
public delegate Task RequestDelegate(HttpContext context); |
Because Task is the base type of Task<T>, generic variance means it's possible to return Task<T> from a method that's used with RequestDelegate. The caller of the delegate never sees the value and it is ignored.
Example: #39956
Proposed API
An analyzer that detects using a method or lambda that returns Task<T> with RequestDelegate and warns the user.
Usage Examples
Task<string> HelloWorld(HttpContext c) => Task.FromResult("Hello " + c.Request.RouteValues["name"]);
endpoints.MapGet("/", HelloWorld); // <- detect bad method
endpoints.MapGet("/", (HttpContext c) => Task.FromResult("Hello " + c.Request.RouteValues["name"])); // <- detect bad lambda
Note that an async lambda can't get in this situation and doesn't need to be checked. The compiler detects a return value and prevents the lambda being converted to RequestDelegate:
RequestDelegate d = new RequestDelegate(async Task<string> (HttpContext context) =>
{
await Task.Yield();
return "hello world"; // <- compiler error
});
Alternative Designs
Risks
Background and Motivation
RequestDelegatecan be used with methods/lambdas that return a value that is then ignored.Delegate signature:
aspnetcore/src/Http/Http.Abstractions/src/RequestDelegate.cs
Lines 6 to 11 in 86c7e01
Because
Taskis the base type ofTask<T>, generic variance means it's possible to returnTask<T>from a method that's used withRequestDelegate. The caller of the delegate never sees the value and it is ignored.Example: #39956
Proposed API
An analyzer that detects using a method or lambda that returns
Task<T>withRequestDelegateand warns the user.Usage Examples
Note that an async lambda can't get in this situation and doesn't need to be checked. The compiler detects a return value and prevents the lambda being converted to
RequestDelegate:Alternative Designs
Risks