Add application startup check that dispatcher is added to request pipeline (#614)

This commit is contained in:
James Newton-King 2018-07-15 11:50:55 +12:00 committed by GitHub
parent 73e4d55d7b
commit 497a38035d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 41 additions and 4 deletions

View File

@ -10,10 +10,14 @@ namespace Microsoft.AspNetCore.Builder
{ {
public static class DispatcherApplicationBuilderExtensions public static class DispatcherApplicationBuilderExtensions
{ {
private const string DispatcherRegisteredKey = "__DispatcherMiddlewareRegistered";
public static IApplicationBuilder UseDispatcher(this IApplicationBuilder builder) public static IApplicationBuilder UseDispatcher(this IApplicationBuilder builder)
{ {
VerifyDispatcherIsRegistered(builder); VerifyDispatcherIsRegistered(builder);
builder.Properties[DispatcherRegisteredKey] = true;
return builder.UseMiddleware<DispatcherMiddleware>(); return builder.UseMiddleware<DispatcherMiddleware>();
} }
@ -21,6 +25,14 @@ namespace Microsoft.AspNetCore.Builder
{ {
VerifyDispatcherIsRegistered(builder); VerifyDispatcherIsRegistered(builder);
if (!builder.Properties.TryGetValue(DispatcherRegisteredKey, out _))
{
var message = $"{nameof(DispatcherMiddleware)} must be added to the request execution pipeline before {nameof(EndpointMiddleware)}. " +
$"Please add {nameof(DispatcherMiddleware)} by calling '{nameof(IApplicationBuilder)}.{nameof(UseDispatcher)}' inside the call to 'Configure(...)' in the application startup code.";
throw new InvalidOperationException(message);
}
return builder.UseMiddleware<EndpointMiddleware>(); return builder.UseMiddleware<EndpointMiddleware>();
} }

View File

@ -34,7 +34,10 @@ namespace Microsoft.AspNetCore.Routing
var feature = httpContext.Features.Get<IEndpointFeature>(); var feature = httpContext.Features.Get<IEndpointFeature>();
if (feature == null) if (feature == null)
{ {
throw new InvalidOperationException("Unable to execute an endpoint because the dispatcher was not run. Ensure dispatcher middleware is registered."); var message = $"Unable to execute an endpoint because the {nameof(DispatcherMiddleware)} was not run for this request. " +
$"Ensure {nameof(DispatcherMiddleware)} is added to the request execution pipeline before {nameof(EndpointMiddleware)} in application startup code.";
throw new InvalidOperationException(message);
} }
if (feature.Invoker != null) if (feature.Invoker != null)

View File

@ -12,7 +12,7 @@ using Xunit;
namespace Microsoft.AspNetCore.Builder namespace Microsoft.AspNetCore.Builder
{ {
public class DispatcherApplicationBuilderExtensions public class DispatcherApplicationBuilderExtensionsTest
{ {
[Fact] [Fact]
public void UseDispatcher_ServicesNotRegistered_Throws() public void UseDispatcher_ServicesNotRegistered_Throws()
@ -69,7 +69,26 @@ namespace Microsoft.AspNetCore.Builder
} }
[Fact] [Fact]
public async Task UseEndpoint_ServicesRegistered_SetsFeature() public void UseEndpoint_ServicesRegisteredAndNoDispatcherRegistered_Throws()
{
// Arrange
var services = CreateServices();
var app = new ApplicationBuilder(services);
// Act
var ex = Assert.Throws<InvalidOperationException>(() => app.UseEndpoint());
// Assert
Assert.Equal(
"DispatcherMiddleware must be added to the request execution pipeline before EndpointMiddleware. " +
"Please add DispatcherMiddleware by calling 'IApplicationBuilder.UseDispatcher' " +
"inside the call to 'Configure(...)' in the application startup code.",
ex.Message);
}
[Fact]
public async Task UseEndpoint_ServicesRegisteredAndDispatcherRegistered_SetsFeature()
{ {
// Arrange // Arrange
var services = CreateServices(); var services = CreateServices();

View File

@ -34,7 +34,10 @@ namespace Microsoft.AspNetCore.Routing
// Assert // Assert
var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await invokeTask); var ex = await Assert.ThrowsAsync<InvalidOperationException>(async () => await invokeTask);
Assert.Equal("Unable to execute an endpoint because the dispatcher was not run. Ensure dispatcher middleware is registered.", ex.Message); Assert.Equal(
"Unable to execute an endpoint because the DispatcherMiddleware was not run for this request. " +
"Ensure DispatcherMiddleware is added to the request execution pipeline before EndpointMiddleware in application startup code.",
ex.Message);
} }
private class ServiceProvider : IServiceProvider private class ServiceProvider : IServiceProvider