aspnet / AspNetWebStack

ASP.NET MVC 5.x, Web API 2.x, and Web Pages 3.x (not ASP.NET Core)
Other
858 stars 354 forks source link

Question of WebApi and Owin on IIS #410

Closed John0King closed 1 year ago

John0King commented 1 year ago

there are many package on nuget for hosting webapi:

and now in Visual Studio , it seem only use Microsoft.AspNet.WebApi.WebHost
and there no document on learn.microsoft.com about webapi + owin + IIS, thats why I ask here.

Microsoft.AspNet.WebApi.WebHost it saids it's support owin, but how does it work ? and where's the position of Microsoft.AspNet.WebApi.Owin ?

I run a owin middleware to set a static AsyncLocal<T> value and find out that this middleware's AsyncLocal<T> is been "cleaned" when the code runs into webapi controller, the only situation I think about is that the owin middleware is running different async flow than webapi.
and I wonder that does webapi controller actully runs inside the owin piepline . I indeed put the app.UseWebApi(config) inside Startup.Configuration() (witch means it use Microsoft.AspNet.WebApi.Owin), and the Microsoft.AspNet.WebApi.WebHost is also installed.

mkArtakMSFT commented 1 year ago

@Tratcher can you look into this one, please? Thanks!

Tratcher commented 1 year ago

WebApi has the following hosting options:

When running on IIS the only reason to include Owin is if you also have other Owin components/middleware that you need to interop with.

If you really want to do that then:

John0King commented 1 year ago

@Tratcher
I'm doing a very simple test and here is the result

1. OwinMiddleare + [ MVC ] or [ WebApi with WebHost ]

//MVC
{
    "From": "Mvc",
    "State": "ExecuteRequestHandler",
    "httpCtx": {
        "Value": 2
    },
    "AsyncLocalCtx": null
}
//webapi
{
    "from": "WebApi",
    "State": "ExecuteRequestHandler",
    "httpCtx": {
        "Value": 2
    },
    "asyncLocalCtx": null
}

2. OwinMiddleware + [Owin WebApi]

//webapi

{
    "from": "WebApi",
    "State": "PreExecuteRequestHandler",
    "httpCtx": {
        "Value": 2
    },
    "asyncLocalCtx": {
        "Value": 2
    }
}

but when I use StateMarker to make my initializeMiddleare run earlier

//   initializeMdilleare run in [PipelineStage.Authenticate]
// and webapi runs in  [PipelineStage.Authorize]
{
    "from": "WebApi",
    "State": "AuthorizeRequest",
    "httpCtx": {
        "Value": 2
    },
    "asyncLocalCtx": null
}

from the result , it seems that the owin middleare runs in different stage that have different async flow ,
and I'm wonder is there a solution to fix it ?

Tratcher commented 1 year ago

IIS/System.Web's integrated pipeline is quite complex, especially for async components. Yes, the Owin components aren't great about transferring async state between pipeline stages and I'm not aware of an easy fix for that. My general recommendation is not to rely on async state, store any request specific information in HttpContext, like in Items, so it automatically flows with the request without relying on any implicit thread state.