Skip to content
This repository was archived by the owner on Nov 20, 2018. It is now read-only.

Commit ed09ae1

Browse files
committed
Implicitly execute matched endpoint at the end of middleware pipeline
1 parent 187e89f commit ed09ae1

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

src/Microsoft.AspNetCore.Http/Internal/ApplicationBuilder.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,13 @@ public RequestDelegate Build()
8181
{
8282
RequestDelegate app = context =>
8383
{
84+
// Implicitly execute matched endpoint at the end of the pipeline instead of returning 404
85+
var endpointRequestDelegate = context.Features.Get<IEndpointFeature>()?.Endpoint?.RequestDelegate;
86+
if (endpointRequestDelegate != null)
87+
{
88+
return endpointRequestDelegate(context);
89+
}
90+
8491
context.Response.StatusCode = 404;
8592
return Task.CompletedTask;
8693
};

test/Microsoft.AspNetCore.Http.Tests/Internal/ApplicationBuilderTests.cs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33

4+
using System.Threading.Tasks;
45
using Microsoft.AspNetCore.Http;
6+
using Microsoft.AspNetCore.Http.Features;
57
using Xunit;
68

79
namespace Microsoft.AspNetCore.Builder.Internal
@@ -20,6 +22,65 @@ public void BuildReturnsCallableDelegate()
2022
Assert.Equal(404, httpContext.Response.StatusCode);
2123
}
2224

25+
[Fact]
26+
public void BuildImplicitlyCallsMatchedEndpointAsLastStep()
27+
{
28+
var builder = new ApplicationBuilder(null);
29+
var app = builder.Build();
30+
31+
var endpointCalled = false;
32+
var endpoint = new Endpoint(
33+
context =>
34+
{
35+
endpointCalled = true;
36+
return Task.CompletedTask;
37+
},
38+
EndpointMetadataCollection.Empty,
39+
"Test endpoint");
40+
41+
var httpContext = new DefaultHttpContext();
42+
httpContext.Features.Set<IEndpointFeature>(new EndpointFeature
43+
{
44+
Endpoint = endpoint
45+
});
46+
47+
app.Invoke(httpContext);
48+
49+
Assert.True(endpointCalled);
50+
}
51+
52+
[Fact]
53+
public void BuildDoesNotCallMatchedEndpointWhenTerminated()
54+
{
55+
var builder = new ApplicationBuilder(null);
56+
builder.Use((context, next) =>
57+
{
58+
// Do not call next
59+
return Task.CompletedTask;
60+
});
61+
var app = builder.Build();
62+
63+
var endpointCalled = false;
64+
var endpoint = new Endpoint(
65+
context =>
66+
{
67+
endpointCalled = true;
68+
return Task.CompletedTask;
69+
},
70+
EndpointMetadataCollection.Empty,
71+
"Test endpoint");
72+
73+
var httpContext = new DefaultHttpContext();
74+
httpContext.Features.Set<IEndpointFeature>(new EndpointFeature
75+
{
76+
Endpoint = endpoint
77+
});
78+
79+
app.Invoke(httpContext);
80+
81+
Assert.False(endpointCalled);
82+
}
83+
2384
[Fact]
2485
public void PropertiesDictionaryIsDistinctAfterNew()
2586
{
@@ -31,5 +92,10 @@ public void PropertiesDictionaryIsDistinctAfterNew()
3192

3293
Assert.Equal("value1", builder1.Properties["test"]);
3394
}
95+
96+
private class EndpointFeature : IEndpointFeature
97+
{
98+
public Endpoint Endpoint { get; set; }
99+
}
34100
}
35101
}

0 commit comments

Comments
 (0)