I'm new on ASP.NET Identity and trying to customize the identity which is provided while creating new MVC project.
ASP.NET Identity automatically creates few tables for handle authentication and authorization itself.
My main goal is just create Users table but others. I've tried following code to prevent creating these tables:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Ignore<IdentityUserRole>();
modelBuilder.Ignore<IdentityUserClaim>();
modelBuilder.Ignore<IdentityRole>();
}
When I want to create a user, following error returning:
The navigation property 'Roles' is not a declared property on type 'ApplicationUser'. Verify that it has not been explicitly excluded from the model and that it is a valid navigation property.
I found that built-in Identity user has following structure:
IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>, IUser, IUser<string>
What I need is creating a custom IdentityUser which not contains role, claim, etc. I just want the table 'Users' when I run the project.
Any possibility to create my own IdentityUser or customize built-in one? Or any suggestion to create just 'Users' table and work with it?
Many thanks in advice.
This is what I did in order to get a solution:
I removed the base.OnModelCreating
Then I added the ignore in this order.
//base.OnModelCreating(modelBuilder);
modelBuilder.Entity<IdentityUser>().ToTable("User");
modelBuilder.Entity<IdentityUser>().ToTable("User").Ignore(p => p.Roles);
modelBuilder.Ignore<IdentityUserRole>();
modelBuilder.Ignore<IdentityUserLogin>();
modelBuilder.Ignore<IdentityUserClaim>();
modelBuilder.Ignore<IdentityRole>();
Doing this I got a final error that it said: Could not drop object 'dbo.Role' because it is referenced by a FOREIGN KEY constraint.
For that I changed the migration moving the DropTable("dbo.Role"). I know this is hack, but I did not find out how EF migrations move the droptables sentences to the right order.
Richard
Related
I have followed on from the following answer here: How to extend IdentityUser with custom property
My variables I have added (following the above answer) are:
int numberID
string fullName
This is built upon the default Visual Studio 2017 ASP.net Web Application selected with options Web API and Individual User Accounts Authentication.
I am now trying to read the current value of both numberID and fullName of the current user inside the ValuesController of the project.
I have tried doing
var currentUser = System.Web.HttpContext.Current.User.Identity.GetUserId();
var currentnumberID = currentUser.numberID;
But am having no sucess with the last line of code.
I have also used User.Identity.GetUserName() and was wondering if there was a way to access my new variables WITHOUT creating a User Identity Extension?
OR
Better yet, with my Web API app what is the best way to add additional variables / fields for the user. Ie I would like to add both fullName and numberID associated to each user and be able to access these in my Web API controllers (eg call for current user and list the variables associated to the current user). I am beginning to think I have taken the wrong road by trying to use UserIdentity.
EDIT
Ended up biting the bullet and following the very easy approach here: How to Get Custom Property Value of the ApplicationUser in the ASP.Net MVC 5 View?
of adding a User Identity extension. Previous answers seemed complicated but that answer was simple and works!
The problem is that you are reading UserId and treating it like User object.
You need to use UserManager, to get the user User object. Inside controller's action method, you have access to UserManager, so you can simply use it:
var currentUser = UserManager.FindById(User.Identity.GetUserId());
If you are not inside controller's action method, then you need to get the UserManager from HttpContext:
var UserManager = HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
I have successfully created custom users and roles within the Asp.Net Identity framework, however one section which is lacking is support for the 'Roles' collection within a User. I added a logical 'Deleted' flag within a UserRole and I want this to be included when EF retrieves the info from the database, however all it does is retrieve everything (which isn't what I want). Senario:
User A has a Role of 'admin' (non-deleted)
I then add a Role of 'super-admin' and then delete 'admin'
If I then access my version of IdentityUser (which has the 'Roles' ICollection - custom type) I still see the 2 roles (1 deleted, 1 not)
What I want to happen is on login (using mostly default functions with various sections overridden), when EF retrieves the data it should know to exclude any row which is flagged as deleted, however I have been unable to find any method of doing this. Because all the boilerplate code is locked, I cannot easily see what is happening or find any logical place to override this functionality.
Can anyone help with this?
You could just scan the roles after login and remove them with code similar to this:
var roles = UserManager.GetRoles(userId);
foreach (var roleName in roles)
{
var role = RoleManager.FindByName(roleName);
if (role.IsDeleted) UserManager.RemoveFromRole(userId, roleName);
}
I am following this really good tutorial to setup a BaseEntity class that will contain 5 fields:
Active, DateCreated, UserCreated, DateModified, UserModified.
All of my entities that need these tracking fields will inherit from this class.
In the small tutorial below he shows me how to override the SaveChanges() method in my dbContext so that these fields will be set properly based on Creation/Updating.
I am trying to figure out how I would store the current logged in user's ID rather than the Name to the UserCreated and UserModified fields
Please let me know if the UserID shouldn't be what I am storing. This is always what I used to do in some of the webforms apps I created back in the day.
Also, what would be the best way to setup Active to always be true when adding new records. Should this be done in the db context also or within my BaseEntity class. I'm thinking I would create a function in the BaseEntity class called Disable() that will change Active=False.
Please view the small tutorial that I am using
You could create a custom implementation of IIdentity/IPrincipal which contains the UserID. Then you can retrieve this value from the Context or Thread and cast it to the correct type.
Set HttpContext.Current.User from Thread.CurrentPrincipal
I have to edit the Login/Registration that ASP provides to include a custom dropdown ("BranchID") menu that saves to the database so each user has its own Branch. I am using ASP Membership system, and of course it saves to the ASPNETMDF database it creates. Googling has net me some results but I am quite confused. I know there are "User Profiles", and I I can save this Profile data, but what I am not quite sure is if its a temporary measure or if it does record to the database.
I could make my own custom membership system, use the built it and adapt it or use the user profiles. What is the best course of action? I'd vastly prefer to adapt/edit the built in Membership system and add the data I require to it but I still don't haven't a clear answer to what I should do or what's best.
You have two choices:
Create a CustomMembershipProvider , and if you need to a CustomRoleProvider, you can do this by implementing .NET's MembershipProvider. Sample: http://www.codeproject.com/Articles/165159/Custom-Membership-Providers
Create a separate table that stores additional user information, i.e., "BranchID", and add a one-to-one relationship between your table and .NET's Membership
It's really up to you which one you choose.
MembershipProvider is pretty easy to extend. Assuming the branch is something they have to select to authenticate? You should be able to extend authenticate to do something like:
public class MyCustomMembershipProvider : MembershipProvider
{
/*
....
*/
public bool ValidateUser(string username, string password, string branch)
{
return (::ValidateUser(username, password) && MyCustomRoutine(username, branch));
}
}
I am in the begining of making a simple website using ASP.NET MVC4 CodeFirst Approach. The web site is built around users who are able to register, make posts etc. The existing UserProfile class was modified for the accommodation other fields (ex: FirstName, LastName etc).
When I ran the website I got a similar error:
Invalid column name 'FirstName'.
Invalid column name 'LastName'.
Invalid column name 'Phone'.
I red that this is because the Database is not updated as the model is updated. So I set the following on the Application_Start() in Global.asax with the intention of droppnng the database always (at least until I get the hang of it).
protected void Application_Start()
{
Database.SetInitializer(new DropCreateDatabaseAlways<UsersContext>());
//Other default generated stuff below...
}
I also tryed the DropCreateDatabaseIfModelChanges, but both methods didn't drop the database.
Isn't this possible? Why is it? Am I doing some thing wrong?
I believe it would be possible to store the info in a different table and link it to this, but I prefer to keep it in one table.
Also is it a bad idea to add UserProfiles to the websites context (lets say: DatabaseContext (which has other entities like Posts, Comments etc) and change the AccountsController to use DatabaseContext instead of UsersContext?
Thanks in advance.
Have you run Enable-Migrations in the Package Manager Console? You should see a migration folder in your project, with a configuration.cs file, ensure you have enabled automatic migrations.
public Configuration(){
AutomaticMigrationsEnabled = true;
//if you drop columns - consider this carefully...
AutomaticMigrationDataLossAllowed = true;
}