Wiring up ASP.Net Identity with Custom Classes
I looked for a simple tutorial that shows how to hook up ASP.Net (Core & .Net) Identity with user generated classes, and I couldn’t really find one. So here are my notes on how to do it. These are rough notes, written quickly. I’ll come back later and update this tutorial so it’s more comprehensive.
The Goal
Create a simple CRUD app in ASP.Net Core 2.1 as well as ASP.Net MVC 5. This app should have user logins via the built in ASP.Net Identity service, and users should be able to save their data independently of other users. For example, a simple ToDo app. A user should be able to register, log in, and create, read, update, and delete their own todos - but other users should not be able to see their todos.
Sounds pretty simple, right? Well, it took me a few hours to figure out.
ASP.net Core 2.1 Example (Razor Pages)
Use Visual Studio templates to create a WebApp with Identities. Build and run to make sure we can log in. Nothing complex here, just tick the boxes in the wizard (or copy and paste into the terminal).
Next, create a custom class. Something like this
public class TodoListItem
{
public int Id { get; set; }
public string Title { get; set; }
public bool isCompleted { get; set; }
public virtual string ApplicationUserID { get; set; }
}
The critical line is the last one. By adding in the ApplicationUserID, we’re setting up a relationship between the auto-generated tables created by ASP.net Identity, and our custom class.
The next thing is to use scafollding to create the CRUD pages from this class. Again, just use Visual Studio’s built in features. Makes sure to choose the existing ApplicationDBContext so that the tables are properly linked.
Once the scaffolding is done, we need to edit the code to bring in the currently logged in user’s User ID. In ASP.Net Core, this is how you do it
ClaimsPrincipal currentUser = this.User;
var currentUserID = currentUser.FindFirst(ClaimTypes.NameIdentifier).Value;
These two lines of code are used in the controller or Razor code behind to get the userID. Once we have the user Id, we can simply set the object’s property directly before we save it.
To retrieve the currently logged in user’s items, use this code
ClaimsPrincipal currentUser = this.User;
var currentUserID = currentUser.FindFirst(ClaimTypes.NameIdentifier).Value;
ToDo = await _context.TodoItem.Where(k => k.ApplicationUserID == currentUserID).ToListAsync();
Again, the important bit is getting the UserID, and then using LINQ to get all items that have the same UserID.
In ASP.NET MVC5, the user ID is returned in a different way.
var currentUserID = User.Identity.GetUserId();
var currentUsersTodo = db.TodoListItems.Where(k => k.ApplicationUserID == currentUserID).ToList();
Adding the DBSet to the DBContext
Once figured out, it’s quite easy to create classes that are linked to the current user. Remember, we have to add the DBSet to the existing DBContext
This is different in .NET Core and .Net MVC.
In .Net Core
The file is called ApplicationDBContext.cs and it’s found inside the “Data” folder.
In .Net MVC 5
The DB Context is inside the IdentityModels.cs file, which is located in the “Models” folder
public DbSet<PriceTracker.Models.GroceryItem> GroceryItem { get; set; }