Migrating from MVC4 to MVC5 and want to use ASP.NET Identity too but I am struggling to find anything that covers everything I think I need to do to migrate the Identity. Migrating an Existing Website from SimpleMembership to ASP.NET Identity suggests all I need to do is create an ApplicationUser
and migrate the data, and other web searches give me sql scripts and passowrd hashing advice. But there are other loose ends that I'd like to clear up before I jump in.
First - I have code to initialise the membership system in my Seed method:
if (!WebSecurity.Initialized)
WebSecurity.InitializeDatabaseConnection(Config.ConnectionStringName,
Config.UsersTableName,
Config.UsersIDColumn,
Config.UserNameColumn,
autoCreateTables: true);
So that needs to go right?
Second - it looks like I need an IdentityDbContext
. So should I change my existing context to inherit that?
i.e. instead of my current code public class SID2013Context : DbContext
do this: public class SID2013Context : IdentityDbContext<ApplicationUser>
Will that generate a migration that creates the new tables I need to support ASP.NET Identity?
Once I've done that I should be able to pull in the AccountController
, Views, ViewModels and start up code that is generated for an MVC5 project.
Can anyone answer the specific questions here and/or point me to a better resource?
I realised that the website I linked to in my question is telling you how to migrate to Identity
tables, but still use SimpleMembership
. I want to use Identity throughout, so I created an empty MVC application using Visual Studio so that I could copy in the code I wanted and fix it up. Here are the steps I followed to get Login and Logout working:
- Added
ApplicationUser.cs
to my Models project
- Added
IdentityConfig.cs
to my App_Start folder
- Added
Startup.Auth.cs
to my App_Start folder
- Added
AccountController.cs
to my Controllers folder (renamed existing controller)
- Added
Startup.cs
to root folder
- Added
AccountViewModels.cs
to ViewModels folder
- Changed my context to inherit
IdentityDbContext
(it does indeed mean that new tables are created in a migration)
- Added the required NuGet packages and fixed up all the namespaces
- Project now builds
- But
Add-Migration
gave an error ... "EntityType IdentityUserRole has no key defined"
- ....solved that by adding a call to
base.OnModelCreating
in my override
Add-Migration
& Update-Database
- adds the tables required
- Added my custom fields in
UserProfile
to ApplicationUser
and updated the database
- Used sql (in a migration) to copy data from old tables to new tables. Sql included here. NB need to populate
SecurityStamp
with a Guid to prevent error during Login
- That's got Login and Logout working
- Removed
UserProfile
, SimpleRoleProvider
and RoleManager
classes - replacing the code where necessary.
- Removed references to
WebMatrix.Data
and WebMatrix.WebData
dlls
- Removed
<roleManager enabled="true" defaultProvider="simple">
and <membership defaultProvider="simple">
from web.config
Sql used in step 14:
INSERT INTO dbo.aspnetusers (id
, email
, emailconfirmed
, passwordhash
, securitystamp
, phonenumber
, phonenumberconfirmed
, twofactorenabled
, lockoutenddateutc
, lockoutenabled
, accessfailedcount
, username
, organisationid
, firstname
, lastname
, inactive)
SELECT
u.id,
u.username Email,
m.isconfirmed EmailConfirmed,
m.password PasswordHash,
--SignInManager.PasswordSignInAsync (used in Login method)
--throws an exception http://stackoverflow.com/a/23354148/150342
NEWID() SecurityStamp,
u.telephone PhoneNumber,
CASE
WHEN u.telephone IS NULL THEN 0
ELSE 1
END PhoneNumberConfirmed,
0 TwoFactorEnabled,
NULL LockoutEndDateUtc,
0 LockoutEnabled,
m.passwordfailuressincelastsuccess AccessFailedCount,
u.username,
u.organisationid,
u.firstname,
u.lastname,
u.inactive
FROM dbo.userprofiles u
INNER JOIN dbo.webpages_membership m
ON m.userid = u.id
WHERE NOT EXISTS (SELECT
1
FROM dbo.aspnetusers
WHERE id = u.id)
INSERT INTO dbo.aspnetroles (id
, name)
SELECT
roleid,
rolename
FROM dbo.webpages_roles r
WHERE NOT EXISTS (SELECT
1
FROM dbo.aspnetroles
WHERE roleid = r.roleid)
INSERT INTO dbo.aspnetuserroles (userid
, roleid)
SELECT
userid,
roleid
FROM dbo.webpages_usersinroles ur
WHERE NOT EXISTS (SELECT
1
FROM dbo.aspnetuserroles
WHERE userid = ur.userid
AND roleid = ur.roleid)