c# - How to create transaction with asp.net identity? -
i doing registration on asking 5 things:
fullname,emailid,password,contactnumber,gender
now emailid , password storing register method , given in below 2 link:
public async task<actionresult> register(registerviewmodel model) { if (modelstate.isvalid) { var user = new applicationuser { username = model.email, email = model.email }; using var context = new myentities()) { using (var transaction = context.database.begintransaction()) { try { var datamodel = new usermaster(); datamodel.gender = model.gender.tostring(); datamodel.name = string.empty; var result = await usermanager.createasync(user, model.password);//doing entry in aspnetuser if transaction fails if (result.succeeded) { await this.usermanager.addtoroleasync(user.id, model.role.tostring()); this.adduser(datamodel, context); transaction.commit(); return view("displayemail"); } adderrors(result); } catch (exception ex) { transaction.rollback(); return null; } } } } // if got far, failed, redisplay form return view(model); } public int adduser(usermaster _adduser, myentities _context) { _context.usermaster.add(_adduser); _context.savechanges(); return 0; }
now below 2 lines:
var result = await usermanager.createasync(user, model.password);//entry done in aspnetusers table. await this.usermanager.addtoroleasync(user.id, model.role.tostring());//entry done aspnetuserrole table
now fullname,contactno,gender having in table usermaster.
so when i submit registration form save details in usermaster , aspnetusers,aspnetuserinrole table.
but consider if there problem occurs while saving record in usermaster dont want save entry in aspnetuser , aspnetuserinrole too.
i create transaction rollback if problem occurs during saving record in table i.e no entry should done in aspnetuser,aspnetuserinrole nd usermaster.
records should saved if there no problem in saving record in 3 tables otherwise whiole transaction should role back.
i using microsoft.aspnet.identity login,register,role management , other , following tutorial:
but await usermanager.createasync , usermanager.addtoroleasync method built in method how synchonize work entity framework.
so can guide me how create such transaction or solve this?
identityconfig:
public class applicationusermanager : usermanager<applicationuser> { public applicationusermanager(iuserstore<applicationuser> store) : base(store) { } public static applicationusermanager create(identityfactoryoptions<applicationusermanager> options, iowincontext context) { var manager = new applicationusermanager(new userstore<applicationuser>(context.get<applicationdbcontext>())); // configure validation logic usernames manager.uservalidator = new uservalidator<applicationuser>(manager) { allowonlyalphanumericusernames = false, requireuniqueemail = true }; // configure validation logic passwords manager.passwordvalidator = new passwordvalidator { requiredlength = 6, requirenonletterordigit = true, requiredigit = true, requirelowercase = true, requireuppercase = true, }; // configure user lockout defaults manager.userlockoutenabledbydefault = true; manager.defaultaccountlockouttimespan = timespan.fromminutes(5); manager.maxfailedaccessattemptsbeforelockout = 5; // register 2 factor authentication providers. application uses phone , emails step of receiving code verifying user // can write own provider , plug in here. manager.registertwofactorprovider("phone code", new phonenumbertokenprovider<applicationuser> { messageformat = "your security code {0}" }); manager.registertwofactorprovider("email code", new emailtokenprovider<applicationuser> { subject = "security code", bodyformat = "your security code {0}" }); manager.emailservice = new emailservice(); manager.smsservice = new smsservice(); var dataprotectionprovider = options.dataprotectionprovider; if (dataprotectionprovider != null) { manager.usertokenprovider = new dataprotectortokenprovider<applicationuser>(dataprotectionprovider.create("asp.net identity")); } return manager; } } // configure application sign-in manager used in application. public class applicationsigninmanager : signinmanager<applicationuser, string> { public applicationsigninmanager(applicationusermanager usermanager, iauthenticationmanager authenticationmanager) : base(usermanager, authenticationmanager) { } public override task<claimsidentity> createuseridentityasync(applicationuser user) { return user.generateuseridentityasync((applicationusermanager)usermanager); } public static applicationsigninmanager create(identityfactoryoptions<applicationsigninmanager> options, iowincontext context) { return new applicationsigninmanager(context.getusermanager<applicationusermanager>(), context.authentication); } }
you should not create new db context, use existing one
var context = request.getowincontext().get<myentities>()
it created per request if use default implementation
app.createperowincontext(applicationdbcontext.create);
update:
ok, since using 2 different contexts code this
public async task<actionresult> register(registerviewmodel model) { if (modelstate.isvalid) { var user = new applicationuser { username = model.email, email = model.email }; var appdbcontext = httpcontext.getowincontext().get<applicationdbcontext>(); using( var context = new myentities()) using (var transaction = appdbcontext.database.begintransaction()) { try { var datamodel = new usermaster(); datamodel.gender = model.gender.tostring(); datamodel.name = string.empty; var result = await usermanager.createasync(user, model.password);//doing entry in aspnetuser if transaction fails if (result.succeeded) { await this.usermanager.addtoroleasync(user.id, model.role.tostring()); this.adduser(datamodel, context); transaction.commit(); return view("displayemail"); } adderrors(result); } catch (exception ex) { transaction.rollback(); return null; } } } // if got far, failed, redisplay form return view(model); } public int adduser(usermaster _adduser, myentities _context) { _context.usermaster.add(_adduser); _context.savechanges(); return 0; }
here appdbcontext same context used usermanager
Comments
Post a Comment