我正在注册,我要求 5 件事:
全名、电子邮件 ID、密码、联系电话、性别
现在我用注册方法存储的电子邮件 ID 和密码在下面的两个链接中给出:
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 even 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 we got this far, something failed, redisplay form
return View(model);
}
public int AddUser(UserMaster _addUser, MyEntities _context)
{
_context.UserMaster.Add(_addUser);
_context.SaveChanges();
return 0;
}
现在下面两行:
var result = await UserManager.CreateAsync(user, model.Password);//entry is done in AspnetUsers table.
await this.UserManager.AddToRoleAsync(user.Id, model.Role.ToString());//entry is done is Aspnetuserrole table
现在这个 Fullname,contactno,gender 我在另一个表中,它是 UserMaster。
因此,当我将提交我的注册表时,我会将此详细信息保存到UserMaster 和AspnetUsers,AspnetUserinrole 表。
但考虑到如果在 UserMaster 中保存记录时出现任何问题,那么我不想在 Aspnetuser 和 Aspnetuserinrole 中也保存条目。
我想创建一个事务,如果在任何表中保存任何记录期间出现任何问题,我将回滚,即不应在 AspnetUser、AspnetUserinRole 和 userMaster 中完成任何条目。
只有在这3个表中保存记录没有问题才能成功保存记录,否则whiole transaction应该返回角色。
我正在使用 Microsoft.AspNet.Identity 进行登录、注册、角色管理等,并遵循本教程:
但是由于 await UserManager.CreateAsync 和 UserManager.AddToRoleAsync 方法内置于方法中,我将如何同步它以使用 Entity Framework 。
那么有人可以指导我如何创建此类交易或任何可以解决此问题的方法吗?
身份配置:
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 for usernames
manager.UserValidator = new UserValidator<ApplicationUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for 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 two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
// You can write your own provider and plug it in here.
manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser>
{
MessageFormat = "Your security code is {0}"
});
manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser>
{
Subject = "Security Code",
BodyFormat = "Your security code is {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 the application sign-in manager which is used in this 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);
}
}
最佳答案
您不应创建新的数据库上下文,而应使用现有的数据库上下文。
var context = Request.GetOwinContext().Get<MyEntities>()
如果您使用默认实现,它是根据请求创建的。
app.CreatePerOwinContext(ApplicationDbContext.Create);
更新:
好的,因为您正在使用两个不同的上下文,您的代码将如下所示:
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;
// Doing entry in AspnetUser even if transaction fails
var result = await UserManager.CreateAsync(user, model.Password);
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 we got this far, something failed, redisplay form
return View(model);
}
public int AddUser(UserMaster _addUser, MyEntities _context)
{
_context.UserMaster.Add(_addUser);
_context.SaveChanges();
return 0;
}
此处,appDbContext
与 UserManager
使用的上下文相同。
关于c# - 如何使用 asp.net 标识创建事务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32858014/