Seriously struggling to have a decent solution to access an int userId value across multiple pages
So I am not an expert. Just when you feel competent a problem like this comes along.
I have a asp.net core razor web app project using Identity (using VS 2022). Identity is working but I really want an int userId rather than a string but totally gave up trying to modify Identity to use an int for userId rather than the default string.
Thus I have implemented a database table with all of my custom user properties that contains the Identity string userId and an int key. That works.
So there are multiple pages where I want to get the int userId.
In a razor page I can use dependency injection to inject the UserManager userManager. I could do that on every razor page where I need the int userId and use GetUserId and then lookup the int userId using a query with the string userId. However, that means replicating the code on every razor page where I need the userId so that is far from a nice solution. I thought I'd try to implement a static class to do it but that doesn't seem to be able to access httpContext.Session so that doesn't work (unless I've missed something).
To complicate matters I thought I could just store the int userId in Session but that will expire so whenever I read the Session variable I would need to check it isn't null and is a valid value and if it isn't refresh the session variable by getting the string userId, finding the int userId and saving it to the session variable. Again putting that code on every page isn't good.
However, if I create a class to do this it doesn't have the dbContext and I again run into the issue that if it is a static class it doesn't seem to have access to the Session.
This feels like it should be such a simple thing but I've got myself into one of those spiralling "what the heck do I do" conditions. I have tried done a lot googling but nothing seems to solve the problem
All Razor pages inherit from the class
PageModel. In your scenario, set Razor pages that "get the int userid" to inherit from a custom page model, as suggested in this SO post.Inheriting from a base page model allows for centralizing code that would otherwise be repeated in each individual Razor page model.
The inherited class provides access to: DI services,
HttpContext,User, etc. In addition, Razor pages that inherit from the base page model can access properties defined in the custom base page model.The following sample shows how to set up an inherited base page model with dependency injection.
Sample notes
The sample uses the
IConfigurationDI service as a substitute for your scenario that requires access to your database service.The property
UserIdAsIntis defined in the inherited base page model. Note that the property is set in theOnGet()method of the Razor view page because theGetUserIdAsInt()method in the inherited class uses theHttpContextobject. This object is not available in the constructor methods of the inherited class or the Razor code-behind class.HttpContextis available once code execution gets to theOnGet()method.MyBasePageModel.cs
This C# class file can be inserted anywhere in your project. You'll just need a
usingstatement in the code-behind.cshtml.csif the namespace is anything other than[ProjectName].Pages.InheritFromBasePageModel.cshtml.cs
InheritFromBasePageModel.cshtml
Program.cs
(Edit 11-Nov-2023)
Using
OnPageHandlerExecutionAsync()overrideThe
MyBasePageModel.csbase page model class above requires each Razor page that inherits from the base page model to add the lineUserIdAsInt = GetUserIdAsInt();in theOnGet()method.This SO post and article show how to execute a method for every
OnGet()handler that inherits from a base page model without adding it to every Razor page.Here's a modified
MyBasePageModel.csclass file that implements theOnPageHandlerExecutionAsync()override method.