Comments (20)
Yes that works if the handler completes synchronously. If it's async then it won't flow to the controller.
@davidfowl , can you please elaborate on this. Did you mean that ExecutionContext
can be lost between PreRequestHandlerExecute
and the next step if Action (on a Controller) processing the request is an async
method? If so then why?
from aspnetkatana.
Why not use httpContext.Items
?
from aspnetkatana.
httpContext will not be propagated across async/await. So we need to set AsyncLocal
. And if we set it in middleware or http module - it will be reset before the controller execution
from aspnetkatana.
httpContext will not be propagated across async/await
What exactly do you mean by that?
So we need to set AsyncLocal
The IIS pipeline isn't a single asynchronous call chain and I don't know if ASP.NET captures and restores the execution context when pipeline events execute.
from aspnetkatana.
Sorry for mixing up the issues. I think there are two I mostly concerned of:
- The context set in middleware will not be propagated to the Controller execution (when running in IIS) and will propagate when running as a self host.
- If we will take dependency on
HttpContext.Current.Items
in middleware (making a special case for IIS) to set context - this context will not propagate into await part of controller when it will run any async task. So we will not be able to correlate telemetry from those parts with the initial request.
I know the limitation of HttpModule
and that Begin
callback will not always execute on the same managed thread as other callbacks. But it is a separate issue.
from aspnetkatana.
The context set in middleware will not be propagated to the Controller execution (when running in IIS) and will propagate when running as a self host.
By "context" you mean async local right?
If we will take dependency on HttpContext.Current.Items in middleware (making a special case for IIS) to set context - this context will not propagate into await part of controller when it will run any async task. So we will not be able to correlate telemetry from those parts with the initial request.
I don't get that part (forgive me). If you set state in httpContext.Items, why wouldn't that flow to the controller action? Also it should be available in HttpContext.Current
...
from aspnetkatana.
In this code condition if (System.Web.HttpContext.Current != null)
be false
. So I need a callback before the Controller execution where I can set the AsyncLocal context. Middleware is a perfect place, but it doesn't work in IIS as this context will be cleared by the host (actually I only checked that CallContext will be cleaned, not AsyncLocal. But I assume it will also be cleaned up. And ideally I want to be able to correlate older FWs as well).
So far the only solution I know if to register Action Filter (like I explained here). It will give the callback I need. However it looks like overkill to register both - middleware for time and other middlewares tracking and Action Filter for correlation inside the Controller.
public async Task<ActionResult> Index()
{
System.Web.HttpContext.Current.Items["a"] = "ctx";
HomeController.ctx.Value = "ctx";
HttpClient client = new HttpClient();
await client.GetStringAsync("http://bing.com").ContinueWith((a) =>
{
if (System.Web.HttpContext.Current != null)
{
var ctxValue = System.Web.HttpContext.Current.Items["a"];
}
var alCtxValue = HomeController.ctx.Value;
});
from aspnetkatana.
Why not just always store the context in the httpContext? Don't use async locals when you're in System.Web...
from aspnetkatana.
Because the httpcontext is null inside the .ContinueWith
. See the example above. So a lot of telemetry will not be correlated. HttpContext is using SynchronizationContext that is not propagated in tasks well.
from aspnetkatana.
But it does work without the .ContinueWith right?
await client.GetStringAsync("http://bing.com");
if (System.Web.HttpContext.Current != null)
{
var ctxValue = System.Web.HttpContext.Current.Items["a"];
}
var alCtxValue = HomeController.ctx.Value;
from aspnetkatana.
ContinueWith does not preserve the SynchornizationContext
(which is the thing that sets httpcontext.current in ASP.NET).
from aspnetkatana.
yes, I have Http Context before and after the await in your example. However it's not enough.
For instance, when on FW 4.5 we collect http calls using EventSource
exposed by HttpWebRequest - those event source calls happens in async context and not being correlated.
Also quite often I need to correlate exception happened in those ContinueWith
.
Yes, sorry I meant SynchronizationContext
, not LogicalCallContext
from aspnetkatana.
I've updated the title of the bug to accurately reflect the request. I don't think it's katana's job to flow the execution context across IIS events.
from aspnetkatana.
Thank you! I do not know enough, but my understanding was that middleware and Controller executes in the same managed thread and Katana explicitly clear up context when in IIS. It would be great if it will not do it when possible
from aspnetkatana.
Thank you! I do not know enough, but my understanding was that middleware and Controller executes in the same managed thread and Katana explicitly clear up context when in IIS
It doesn't have anything to do with the same thread per se but the fact that they run in different IIS events is the problem. The execution context isn't preserved between these 2 events. You can see this by looking at the "call stack" during controller execution. You'll see the middleware pipeline isn't there.
from aspnetkatana.
Just discussed it with @lmolkova. So re-setting the AsyncLocal
in PreRequestHandlerExecute
will solve the issue? If so - we can close the issue as it is a good workaround for me
from aspnetkatana.
Yes that works if the handler completes synchronously. If it's async then it won't flow to the controller.
from aspnetkatana.
@SergeyKanzhelev I assume you got unblocked, so closing this. But if that's not the case, let me know and I'll reactivate.
from aspnetkatana.
Using something like HttpContext.Current is not a good idea at all. It does not work outside IIS, and inside IIS it has a lot of limitations. I've configured Owin, web API, OData, signalr, entity framework with Autofac, and I pass a per request instance of my own ILogger into all classes I need logging using constructor injection, so in my continueWith call I've a direct reference to my ILogger. Combining this with DRY concept will make a very powerful approach for logging which works anywhere
from aspnetkatana.
Remember that things have changed too in .NET Core. my approach is working fine on .NET Core 2 too
from aspnetkatana.
Related Issues (20)
- How to debug OpenIdConnect authentication issues? HOT 12
- Could not load file or assembly Microsoft.Live.Base exception HOT 3
- Unauthorized error 401.0 for Asp.net mvc site with IIS anonymous authentication HOT 8
- /signin-oidc is not found HOT 7
- 'OwinStartupAttribute' is inaccessible due to its protection level HOT 3
- GetExternalLoginInfoAsync() return null for facebook only HOT 6
- Having vulnerabilities on Microsoft.Owin.Security.OpenIdConnect, 4.2.2 HOT 2
- ClockSkew Ignored by OAuthBearerAuthenticationHandler HOT 2
- Requests are run on IOCP threads by default in OwinHttpListener HOT 5
- Attempt to access method System.Management.Instrumentation.InstrumentedAttribute..ctor(System.String) in violation of security transparency rules failed. HOT 2
- Question: Why does the 4.2.2 package specifically require .NET Framework 4.5? HOT 2
- System.NullReferenceException: Object reference not set to an instance of an object HOT 9
- App redirects to different Auth Type refresh token URL. HOT 4
- Strange behavior on port 50000 for Owin self hosting.... HOT 8
- OpenIdConnectProtocolValidator cannot validate state HOT 4
- Should OIDC middleware be refreshing a `code id_token` when close to expiry? HOT 3
- Session in ASP.NET WebForm is cleared after authenticated by Entra ID with CookieAuthentication and WsFederationAuthentication HOT 2
- Always a object reference error when trying to host a webapi in owin self hosted HOT 3
- owin.RequestId always empty guid string HOT 3
- Microsoft.Owin.Security.WsFederation has a vulnerable Newtonsoft.Json package dependency HOT 10
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from aspnetkatana.