C
C#17mo ago
Johannes M

❔ Using HttpContext outside of a controller/request pipeline (.NET 7)

Hi there I am currently busy with porting a "legacy" system from .NET Framework MVC to .NET Core MVC 7 and struggling with implementing some "global" state. Previously the project used the static accessor from System.Web but whenever I try using IHttpContextAccessor outside of a controller or a service I am calling inside of a controller I do not have access. I would like to have a class where I can store some static properties that I use throughout the project. Currently I am trying to use the Session State but when using it outside of the request pipeline the HttpContext will be null. I have some classes that are not used inside of a controller that need access to the HttpContext Session State. I have created a scoped service that I can call inside of controllers or request pipeline and the functionality works but once I step outside of the pipeline I have no access. Any advice is welcome. Behavior trying to replicate:
public static int ClientID
{
get { return Convert.ToInt32(HttpContext.Current.Session["clientid"]); }
set { HttpContext.Current.Session["clientid"] = value; }
}
public static int ClientID
{
get { return Convert.ToInt32(HttpContext.Current.Session["clientid"]); }
set { HttpContext.Current.Session["clientid"] = value; }
}
14 Replies
Pobiega
Pobiega17mo ago
As you said, when used outside the http request pipeline it will be null. It doesnt even make sense, since you have no session outside the pipeline either Why does the user id need to be static? You can't know what user you are dealing with outside a request either, assuming normal asp workflow
Johannes M
Johannes MOP17mo ago
Does not need to be static but that was the previous implementation done with framework 4.8, I basically need to bring this up to .NET 7 standards of doing things. A lot of data was stored inside of the session state so that it can be pulled at any point in time using some thing like
public static class cCore {
public static int ClientID
{
get { return Convert.ToInt32(HttpContext.Current.Session["clientid"]); }
set { HttpContext.Current.Session["clientid"] = value; }
}
}


public class SettingsController : Controller {
public ActionResult SetUserSettings(TModel model) {
var userSettings = cUser.SaveUserSettings(model, cCore.ClientID);
}
}
public static class cCore {
public static int ClientID
{
get { return Convert.ToInt32(HttpContext.Current.Session["clientid"]); }
set { HttpContext.Current.Session["clientid"] = value; }
}
}


public class SettingsController : Controller {
public ActionResult SetUserSettings(TModel model) {
var userSettings = cUser.SaveUserSettings(model, cCore.ClientID);
}
}
So basically instead of constantly reaching out and getting that session state value, you have a class that just does that and you can call the prop.
Pobiega
Pobiega17mo ago
But sessions is an asp concept You don't have a session outside of the http request pipeline You need some other way of knowing what user you are operating on. Preferably passing it
Johannes M
Johannes MOP17mo ago
What would you say would be the best way of keep track of variables that should stay constant throughout a session's lifetime i.e. I have some helper classes that use the values stored in the session to dynamically create menu items for the sidebar and topbar?
Pobiega
Pobiega17mo ago
?? Oh, I see. I mean that's fine to be in session? When do you ever render a view outside a http request?
Johannes M
Johannes MOP17mo ago
The whole menu stuff are part of the layout and change based off of some of the values (it is a multi-tenant system) so certain things like user permissions and actions are based off those values that get stored in session and then the menu will render based on what is set in the session. if you have permissions for a certain path it will show and if not it will not show.
Pobiega
Pobiega17mo ago
Sure. Not sure when you need this outside of a request still
Johannes M
Johannes MOP17mo ago
@pobiega we are basically trying to imitate what a JS framework can do in terms of having Global State that only get mutated when needs be.
Pobiega
Pobiega17mo ago
But a js framework app runs per client Asp does not Ie, of you and me both run the same js app, we have different instances and can't share Global state But in asp, the server runs once and has shared global state This is why we avoid global state.
Johannes M
Johannes MOP17mo ago
You're right. Unfortunately I do not know of the best way to implement the session state scenario without having to constantly hit the db to populate the session values per request. because I can do it when a user logs in but when the auth session is still valid it basically hits the home controller and continues to try access the session state values to run other methods
Pobiega
Pobiega17mo ago
Seems fine to me Session storage is usually just an in-memory cache by defau The problem is that you seemed to be trying to access session-specific information outside of a request, and thtmat is just not possible You can't identify the session outside a request. You might have multiple users at once
Johannes M
Johannes MOP17mo ago
Alright, I will have to find a workaround for this. Thank you @pobiega
Pobiega
Pobiega17mo ago
Sure. I don't fully understand the problem thou, generating a menu should reasonably never be done outside a request 🙂
Accord
Accord17mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server