Reputation: 6261
When creating an (unbranched) OWIN pipeline, stage-markers are respected.
But when using a branched pipeline (with app.Map
or app.MapWhen
) all middleware in each branch runs at the stage of the first stage-marker encountered.
Is there any way to use stage-markers within a branch?
To illustrate the problem I'm using a modified version of the Katana branching pipeline demo
public void Configuration(IAppBuilder app)
{
app.Use<AddBreadCrumbMiddleware>("start-of-the-line");
app.Map("/branch1", app1 =>
{
app1.Use<AddBreadCrumbMiddleware>("took-branch1");
app1.Use<AddBreadCrumbMiddleware>("more-in-branch1");
// Nesting paths, e.g. /branch1/branch2
app1.Map("/branch2", app2 =>
{
app2.Use<AddBreadCrumbMiddleware>("took-branch2");
app2.Use<DisplayBreadCrumbs>();
});
app1.Use<DisplayBreadCrumbs>();
});
For the path: /branch1/branch2
this outputs the expected result:
start-of-the-line (stage: PreHandlerExecute), took-branch1 (stage: PreHandlerExecute), more-in-branch1 (stage: PreHandlerExecute), took-branch2 (stage: PreHandlerExecute)
Now I add some stage markers:
app.Map("/branch1", app1 =>
{
app1.Use<AddBreadCrumbMiddleware>("took-branch1");
app1.UseStageMarker(PipelineStage.Authenticate);
app1.Use<AddBreadCrumbMiddleware>("more-in-branch1");
app1.UseStageMarker(PipelineStage.Authorize);
// Nesting paths, e.g. /branch1/branch2
app1.Map("/branch2", app2 =>
{
app2.Use<AddBreadCrumbMiddleware>("took-branch2");
app2.UseStageMarker(PipelineStage.PostResolveCache);
app2.Use<DisplayBreadCrumbs>();
});
app1.Use<DisplayBreadCrumbs>();
});
This time the output for the same path is:
start-of-the-line (stage: Authenticate), took-branch1 (stage: Authenticate), more-in-branch1 (stage: Authenticate), took-branch2 (stage: Authenticate)
Can anyone explain why everything runs at the Authenticate
stage and whether there is a workaround to respect the other stage markers in branches?
Upvotes: 5
Views: 1166
Reputation: 4373
Surfacing the comment as an answer:
By design. Stage markers are only supported in the root pipeline. Otherwise you may miss taking a branch. – Tratcher Oct 20 '15 at 1:19
So yes as the question states, "when using a branched pipeline (with app.Map
or app.MapWhen
) all middleware in each branch runs at the stage of the first stage-marker encountered."
With that context, a note for using SignalR: when calling one of the SignalR OWIN extensions, such as MapSignalR
or RunSignalR
, those explicitly set the stage marker to avoid having a session state:
// We need to make that SignalR runs before any handlers are
// mapped in the IIS pipeline so that we avoid side effects like
// session being enabled. [...]
builder.UseStageMarker(PipelineStage.PostAuthorize);
This means that if you configure SignalR in your OWIN app, _all_ requests, including non-signalr requests, will run at that same stage, without HttpContext.Current.Session
or HttpContext.Current.CurrentHandler
.
Upvotes: 2