【问题标题】:How to store new users into database from Configuration in MVC5?如何将新用户从 MVC5 中的配置存储到数据库中?
【发布时间】:2014-09-10 20:45:18
【问题描述】:

我有一个继承自 ApplicaitonUser 的模型,定义如下:

public class Business : ApplicationUser
{
    ...
}

然后,在我的配置中,我从 CSV 文件中读取所有信息,并创建一个业务对象列表。然后,我想将他们全部创建为新用户并将其添加到数据库中,并给他们一个默认密码(稍后我会通过电子邮件向列表中的所有用户发送密码,以便他们可以更改密码)。我想我需要使用 UserManager.CreateAsync 方法,但我似乎无法从我的配置文件中引用它。

目前,我有这样的事情,我从 CSV 文件中读取了所有业务特定信息:

        foreach (string csv in csvs)
        {
            using (CsvReader reader = new CsvReader(csv))
            {
                foreach (string[] values in reader.RowEnumerator)
                {
                    businesses.Add(new Business
                    {
                        BusinessName = values[0],
                        Email = values[1],
                        Address = values[2],
                        City = values[3],
                        StateID = states.Single(s => s.StateCode == values[4]).StateID,
                        Zip = values[5],
                        Phone = values[6],
                        Fax = values[7],
                        SICCode = values[8],
                        Description = values[9],
                        Website = values[10]
                    });
                }
            }
        }

然后,我想我需要一个类似于下面的 foreach 语句来遍历所有业务,但我不知道这是否是正确的方法,即使是,我如何访问来自 Configuration.cs 文件的 UserManager?我似乎无法从配置中访问它。

        foreach (Business b in businesses)
        {
            var result = await UserManager.CreateAsync(b, "MyPassword");
        }

【问题讨论】:

  • 您能否在 Business Class 中添加一个密码字段并在创建新 Business 时为其分配一个默认值 { } 您能否展示一下 Business 是如何完全定义的
  • @DJKRAZE 我的商务舱包括以上所有字段。电子邮件除外。关键是它继承自ApplicationUser,所以它也有它的所有字段,从那里来的Email字段。我的问题是如何创建新用户并将它们从配置文件存储在数据库中。我想我需要类似下面的 foreach 语句。但是,我根本无法从我的配置文件中访问 UserManager。设置默认密码是没有问题的,而 CreateAsync 接受两个参数,一个是 ApplicationUser,一个是密码。
  • 你说的Configuration.cs文件是什么意思?您是否尝试为数据库播种?
  • @ett 有点晚了,但我发布了一个关于如何使用 EF 配置文件为数据库播种的答案。

标签: c# asp.net-mvc entity-framework csv asp.net-identity


【解决方案1】:

至于访问UserManager,可以新建一个:

new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));

如果在 Startup.Auth.cs 中正确设置,则从当前 HttpContext 获取一个:

HttpContext.Current.GetOwinContext().GetUserManager<ApplicationUserManager>()

现在,如果这是种子数据,那么这种逻辑可能不应该存在于 Web 应用程序本身中。如果您确实想通过读取 csv 文件以编程方式进行播种,请考虑编写一个单独的控制台应用程序,该应用程序与您的 csv 文件一起在本地拥有,并在您需要为特定数据库进行播种时运行此应用程序。

然后您也可以使用 UserManager 跳过此 ApplicationUser 基础结构,为简单起见,仅生成您正在使用的数据库的数据库优先模型,并让 EF 照常插入数据。

编辑:哦,是的,密码的东西。所以你仍然可以使用 UserManager 基础设施来解决所有问题,或者如果你想绕过 UserManager 的其他部分,你可以手动使用UserManager.PasswordHasher.HashPassword("Password")

【讨论】:

    【解决方案2】:

    虽然公认的解决方案有效,但我认为这提供了更好的选择。这是一篇关于我使用的数据库播种的文章:link。以下是我用来匹配您的情况的代码细分。

    在您的 DbContext 构造函数中,您可以指定一个引用您的 Configuration.cs 文件的数据库初始化程序。初始化器的类型有多种选择,您可以在here 找到它们。

        public ApplicationDBContext()
            : base("DefaultConnection")
        {
            Database.SetInitializer(new MigrateDatabaseToLatestVersion<ApplicationDBContext, IBCF.Core.Migrations.Configuration>());
        }
    

    一旦您在配置文件中指定了这一点,您就可以添加一个种子函数,该函数使用 CSV 中的项目填充您的数据库。这样做将允许您将数据播种到数据库中,而无需将代码放入您的 Web 项目中,也无需创建单独的应用程序。

    internal sealed class Configuration : DbMigrationsConfiguration<IBCF.Core.ApplicationDBContext>
    {
        public Configuration()
        {
            AutomaticMigrationsEnabled = true;
        }
    
        protected override void Seed(IBCF.Core.ApplicationDBContext context)
        {
            //Initialize managers
            var userManager = new UserManager<Business>(new UserStore<Business>(context));
    
            //Do something to populate your csvs variable
    
            foreach (string csv in csvs)
            {
                using (CsvReader reader = new CsvReader(csv))
                {
                    foreach (string[] values in reader.RowEnumerator)
                    {
                        var business = new Business
                        {
                            BusinessName = values[0],
                            Email = values[1],
                            Address = values[2],
                            City = values[3],
                            StateID = states.Single(s => s.StateCode == values[4]).StateID,
                            Zip = values[5],
                            Phone = values[6],
                            Fax = values[7],
                            SICCode = values[8],
                            Description = values[9],
                            Website = values[10]
                        };
    
                        userManager.Create(business, "MyPassword")
                    }
                }
            }
    
            context.SaveChanges();
        }
    }
    

    【讨论】:

    • 谢谢,我去看看。我也采用了类似的方法。我会让你知道结果。
    • 我同意这是一个可行的方法,但是 Database.SetInitializer 真的应该在 DbContext 的构造函数中吗?将它放在 Global.asax 的 Application_Start 中不是更好吗?
    • 这个问题有一些关于将初始化程序放在哪里的好方法。 (stackoverflow.com/questions/8679562/…) 总的来说,我认为这是一个偏好/项目配置的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-21
    • 2014-03-26
    • 1970-01-01
    • 1970-01-01
    • 2021-05-30
    • 2011-05-23
    • 2011-06-26
    相关资源
    最近更新 更多