c# - 如何使用 ASP.NET Identity(Web 表单)将数据保存在数据库中?

标签 c# asp.net webforms asp.net-identity

这个问题是以下章节的下一章: How to add custom table in ASP.NET IDENTITY?

在第一章中,我询问了如何在 ASP.NET Identity 中创建自定义表。 在本章中,我将询问如何将数据保存在数据库中。我尝试了很多方法,但都没有成功。

成功登录后,系统应该存储一些数据,例如:

  • [AccountLogID] PK
  • [IPv4]
  • 登录日期
  • [UserId] FK(来自 User.ID)

我的代码如下所示:

IdentityModels.cs

namespace Web_WebApp.Models
{
    // You can add User data for the user by adding more properties to your User class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
    public class ApplicationUser : IdentityUser
    {


        public virtual ICollection<AccountLog> AccountLogs { get; set; }


        public ClaimsIdentity GenerateUserIdentity(ApplicationUserManager manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = manager.CreateIdentity(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }

        public Task<ClaimsIdentity> GenerateUserIdentityAsync(ApplicationUserManager manager)
        {
            return Task.FromResult(GenerateUserIdentity(manager));
        }

    }


    public class AccountLog
    {
        [Key]
        public Guid AccountLogID { get; set; }

        public string IPv4 { get; set; }
        public DateTime LoginDate { get; set; }
        public string UserId { get; set; }

        [ForeignKey("UserId")]
        public virtual ApplicationUser User { get; set; }
    }

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>


    {
        public ApplicationDbContext()
            : base("Web_Identity", throwIfV1Schema: false)
        {
        }


        public System.Data.Entity.DbSet<AccountLog> AccountLog { get; set; }



        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }


    }
}

登录.aspx.cs

namespace Web_WebApp.Account
{
    public partial class Login : Page
    {

        string GuidToken = System.Guid.NewGuid().ToString();



        public static string GetExternalIP()
        {
            try
            {
                string externalIP;
                externalIP = (new WebClient()).DownloadString("http://checkip.dyndns.org/");
                externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"))
                             .Matches(externalIP)[0].ToString();
                return externalIP;
            }
            catch { return null; }
        }


        protected void LogIn(object sender, EventArgs e)
        {
            // Validate the user password

            //var AccountLogs = Context.GetOwinContext().GetUserManager<AccountLog>();
            var manager = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
            var signinManager = Context.GetOwinContext().GetUserManager<ApplicationSignInManager>();

            // Require the user to have a confirmed email before they can log on.
            var user = manager.FindByName(username.Text);

            if (IsValid)
            {


                if (user != null)
                {

                    {
                        // This doen't count login failures towards account lockout
                        // To enable password failures to trigger lockout, change to shouldLockout: true
                        var result = signinManager.PasswordSignIn(username.Text, Password.Text, RememberMe.Checked, shouldLockout: true);

                        if (!user.EmailConfirmed && result == SignInStatus.Success)
                        {


                            Response.Redirect("/Account/Confirmation?UserConfirmationID=" + user.Id);
                        }


                        switch (result)
                        {
                            case SignInStatus.Success:

                                var AccountLog = new AccountLog()
                                {

                                    IPv4 = GetExternalIP(),
                                    LoginDate = DateTime.Now,
                                    UserId = user.Id,

                                };

                                user.AccountLogs.Add(AccountLog);


                                IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response);

                                break;
                            case SignInStatus.LockedOut:
                                //Response.Redirect("/Account/Lockout");

                                FailureText.Text = "This account has been locked, please try again later.";
                                ErrorMessage.Visible = true;
                                return;

                            case SignInStatus.RequiresVerification:
                                Response.Redirect(String.Format("/Account/TwoFactorAuthenticationSignIn?ReturnUrl={0}&RememberMe={1}",
                                                                Request.QueryString["ReturnUrl"],
                                                                RememberMe.Checked),
                                                  true);
                                break;
                            case SignInStatus.Failure:
                            default:
                                FailureText.Text = "Invalid password";
                                ErrorMessage.Visible = true;
                                break;

                        }


                    }


                }
                else
                    FailureText.Text = "Account not found.";
                ErrorMessage.Visible = true;
            }
        }
    }
}

使用这些代码,我的应用程序运行,我可以登录,但它不会保存我在代码中提到的任何内容。我没有收到任何错误或警告。

我确定缺少“SaveChanges()”之类的内容,但我不知道该把它放在哪里。

感谢您为解决我的问题所做的努力。

最佳答案

您通过 ApplicationUserManager 获取用户,在向集合 user.AccountLogs 添加新的 AccountLog 条目后,您将需要将用户保存回数据库。 AFAIK 您可以从 OWIN 获取 Entity Framework 上下文(ApplicationDbContext?),就像获取其他实例一样。

switch (result)
{
    case SignInStatus.Success:

        var AccountLog = new AccountLog()
        {

            IPv4 = GetExternalIP(),
            LoginDate = DateTime.Now,
            UserId = user.Id,
        };

        user.AccountLogs.Add(AccountLog);

        // get the entity framework context.
        var dbContext = Context.GetOwinContext().Get<ApplicationDbContext>();
        // save the changes to objects tracked by this context
        dbContext.SaveChanges();


        IdentityHelper.RedirectToReturnUrl(Request.QueryString["ReturnUrl"], Response);

        break;
case SignInStatus.LockedOut:
 // removed for brevity.
    break;

}

注意:您可能必须直接从上下文中再次获取用户,但我认为没有必要,取决于用户是否分离

关于c# - 如何使用 ASP.NET Identity(Web 表单)将数据保存在数据库中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31964431/

相关文章:

c# - 将 PDF 转换为图像 - 库或命令行 - 免费

c# - 如何使用 basicHttpBinding(SOAP,而非 REST)启用 Wcf 帮助页面

jquery - 如何在剑道网格中加载大量数据

c# - 在 div 的后台 url 中求值

c# - 子弹不会向前移动,而是停留在枪的位置

c# - 使用 Caliburn 的 TextboxHelper.ButtonCommand 绑定(bind)

c# - 直接编辑模式下的 Gridview

asp.net - 如何从 `.js` 文件访问服务器端上下文?

asp.net:__doPostBack 有时不呈现

asp.net - Ninject、ASP.NET 和自定义控件