【问题标题】:Moving ASP.NET Identity model to class library将 ASP.NET 标识模型移动到类库
【发布时间】:2014-05-03 16:19:27
【问题描述】:

我正在尝试使用此链接中的方法将 Identity 模型移动到类库:

ASP.NET Identity in Services library

问题 1:似乎一直在使用网站项目的连接字符串。我通过在类库中指定完整的连接字符串来克服它。我可以让 IdentityDbContext 使用类库的连接字符串吗?

问题 2:由于问题 1,如果我从网站项目中删除实体框架。它会给出以下错误,它正在网站项目中寻找 EF 的 SqlClient。

EntityFramework.dll 中出现“System.InvalidOperationException”类型的异常,但未在用户代码中处理

附加信息:未找到具有不变名称“System.Data.SqlClient”的 ADO.NET 提供程序的实体框架提供程序。确保提供程序已在应用程序配置文件的“entityFramework”部分注册。请参阅http://go.microsoft.com/fwlink/?LinkId=260882 了解更多信息。

欢迎使用其他解决方案,只要它在网站项目中省略所有数据访问层引用,如 EF。

【问题讨论】:

  • 也许这会有所帮助。 stackoverflow.com/a/29519572/1467014 。我唯一要做的就是删除控制器中的一些 ef 引用。然后,除非我错过了什么,否则我的 web 项目中没有其他 ef 依赖项。
  • 如果我理解正确的话,连接字符串应该放在网站项目的 web.config 中......因为所有配置都应该放在 main(){.. .},在 ASP.NET Web 应用程序中是 Startup.cs 类或网站项目中的 Global.asax。
  • 我认为您总是需要在您的网站项目中引用 EF,因为您的配置中需要来自 EF 的 DbContext。

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


【解决方案1】:

要将 IdentityModel 移动到类库中(根据SRP,这是正确的做法),请执行以下步骤:

  1. 创建一个类库。 (ClassLibrary1)
  2. 使用 NuGet,添加对 Microsoft.AspNet.Identity.EntityFramework 的引用。这也会自动添加一些其他引用。
  3. 在您的网站中添加对 ClassLibrary1 的引用
  4. 找到 WebSite/Models/IdentityModel.cs 并将其移至 ClassLibrary1。
  5. 使 IdentityModel.cs 看起来像这样:

    public class ApplicationUser : IdentityUser
    {
    }
    
    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()
            : base("YourContextName")
        {
        }
    }
    
  6. 确保您网站的 Web.config 中有 YourContextName 指向该部分中的正确数据库。 (注意:这个数据库可以而且应该存放您的应用程序数据)。

    <add name="YourContextName" connectionString="YourConnectionStringGoesHere"
      providerName="System.Data.SqlClient" />
    
  7. 让您的 EF Context 类继承自您的 ApplicationDbContext:

    public class YourContextName : ApplicationDbContext
    {
        public DbSet<ABizClass1> BizClass1 { get; set; }
        public DbSet<ABizClass2> BizClass2 { get; set; }
        // And so forth ...
    }
    

当您站点中的任何人尝试登录或注册时,身份系统会将他们路由到您的数据库,其中包含您的所有数据,其中包括身份表。

一切顺利!

【讨论】:

  • 我还建议将 ApplicationDbContext 拆分到 IdentityModels 文件之外的数据项目中的自己的文件中
  • 我试图实现这一点,但在使用 ASP.net 身份框架时没有找到拥有模型/数据/服务/演示的好方法。我不需要将我的数据访问层(实体框架)加载到我的核心程序集中来创建我的模型。
  • @Sam,将您的模型移动到单独的组件中(您的其余模型已经在其中,对吗?)。然后从那里引用它们。
  • @MattMombrea,我也是这样做的。数据访问管道与模型位于同一文件/程序集中,这闻起来很奇怪。我真的希望 MS 能够遵循一些(任何?)可靠的设计模式来构建他们的“开箱即用”功能。新开发人员弹出一个新的 MVC 模板,看到模型类旁边的数据访问代码,并认为既然 MS 是这样做的,我也应该这样做!
  • 我非常喜欢这个解决方案。我需要这样做,所以我在 github 上发布了这个解决方案的版本:github.com/jjroman/ASPNetIdentityToLib。希望对其他开发者有所帮助。
【解决方案2】:

@Rap 对 EF6 和 Identity 2.0 的回答的更新:

  1. 创建一个类库。 (ClassLibrary1)
  2. 使用 NuGet,添加对 Microsoft.AspNet.Identity.EntityFramework 和 Microsoft.AspNet.Identity.Owin 的引用。
  3. 在您的网站中添加对 ClassLibrary1 的引用
  4. 找到 WebSite/Models/IdentityModel.cs 并将其移至 ClassLibrary1。
  5. IdentityModel.cs 应该是这样的,无需更改任何内容:

    public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager, string authenticationType)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);
            // Add custom user claims here
            return userIdentity;
        }
    }
    
    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()
            : base("DefaultConnection", throwIfV1Schema: false)
        {
        }
    
        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }
    }
    
  6. 确保您网站的 Web.config 具有指向该部分中正确数据库的上下文。 (注意:这个数据库可以而且应该存放您的应用程序数据)。

    <connectionStrings>
      <add name="DefaultConnection" connectionString="Data Source=localhost;Initial Catalog=Project;Integrated Security=sspi;Pooling=false;" providerName="System.Data.SqlClient" />
    </connectionStrings>
    
  7. 让您的 EF Context 类继承自您的 ApplicationDbContext:

    public class YourContextName : ApplicationDbContext
    {
        public DbSet<ABizClass1> BizClass1 { get; set; }
        public DbSet<ABizClass2> BizClass2 { get; set; }
        // And so forth ...
    }
    

【讨论】:

  • 如何解决 EF 中的 DbContext 类是自动生成的问题?需要修改tt模板吗?
  • @freedeveloper 我不明白你的问题?以上回答有效。
  • 感谢您的回答。问题是 EF 中的 DbContext 是由模板自动生成的。如果我修改数据库,则会再次生成类并且我的更改会丢失。 EF中的模型是DB优先
  • @freedeveloper 您需要使用 EF Code-First 方法。
【解决方案3】:

将 Identity 移入类库是什么意思?用作参考?我的自定义用户管理器和用户在一个单独的库中,但仅此而已。

身份信息需要某种数据存储。如果您将 Identity 配置为使用 EF,请务必为其获取额外的 nuget 包,并且您应该能够在创建上下文时传递连接字符串。

在我的头顶...

var mgr = new UserManager<ApplicationUser>(
     new IUserStore_ofYourChoice<ApplicationUser>(
       new DbContextName("ConnectionStringOverload"));

我认为 EF 存储是“UserStore”,需要验证。

现在有近十几种不同的用于 Identity 数据存储的 nuget 包。您不必使用 EF,但它需要某种存储。

** 编辑 **

另外,作为参考,默认情况下,它将始终使用主项目的配置,因此它定义的连接字符串,这就是它的假设工作方式,所以没关系。

【讨论】:

  • 我已经在我的问题(问题 1)上说过,我为 Identitycontext 放置了完整的连接字符串。我进一步发现,如果我使用 DB 1st 方法,我无法覆盖上下文连接字符串。甚至我可以在类库中执行所有操作来创建/管理模型。运行时,会出现无法在 web.config 文件中找到连接字符串的错误。当然它不在 asp.net 项目中,它应该在类库 app.config 中。
  • 使用DataSet设计器没有问题,它可以将DAL完全拆分到一个类库中。然后由 asp.net 项目使用,无需任何连接字符串。
【解决方案4】:

您必须了解并记住一些规则。

首先,Web 项目将始终且仅使用它在自己的项目中找到的 web.config 文件 - 期间。您在解决方案的其他任何位置放置任何其他配置文件都没有关系。 Web 项目只能使用它在自己的项目中找到的内容。如果在另一个项目中有连接字符串,则必须将其复制到 web 项目中,否则将永远找不到。

其次,假设 Web 项目是您的启动项目,并且假设您正在使用数据迁移(因为 Identity 使用它),请注意包管理器将始终使用它在启动项目中找到的连接字符串。因此,更新数据库的包管理器不会使用模型项目中的连接字符串。

简单的解决方案是: 1. 将连接字符串从模型项目复制到 Web 项目。 2. 在包管理器控制台中,确保选择上下文的下拉菜单指向您的模型项目。

【讨论】:

    【解决方案5】:

    我想我参加聚会有点晚了,但对于未来的读者来说,here's 是个好书。

    【讨论】:

    • 不确定为什么它被否决,解释了 OP 的要求:引用:“其他解决方案是受欢迎的,只要它在网站项目中省略所有数据访问层引用,如 EF。”我在寻找类似问题的解决方案时偶然发现了这个页面,其他人将来也会这样做。投反对票的人能否解释投反对票的原因?
    • 我想我也有点迟到了:你被否决了,因为你的全部答案都是一个链接。不鼓励这样做,因为链接可能会过期(或更改内容),然后您的答案将变得毫无价值。 PS:我不是投反对票的人,只是想提供帮助。
    • 酷,感谢您的反馈。那么在这种情况下有什么建议呢?该链接是一个4篇系列,我应该复制粘贴4篇文章并感谢作者吗?
    • 一般来说,您会希望包含链接中专门回答您原始问题的相关部分。也许可以这样想:如果另一个用户将此作为答案发布,您会发现它作为 答案 有用吗?如果您觉得这在这种特定情况下没有意义/适用,那么也许更好的地方是对您的原始问题进行编辑?
    • 另外,我没有收到您回复我评论的提醒:“帖子作者将始终收到您的评论的通知。同时通知之前的评论者 ,提及他们的用户名......“。 @ShaiCohen 在我的例子中。这就是为什么你不需要我标记你的名字就可以收到警报,但我没有。
    【解决方案6】:

    问题1:-

    我想可以使用以下链接中的解决方案:-

    Setup Entity Framework For Dynamic Connection String

    问题2:-

    我相信实体框架的构建方式在执行时将使用该项目的 web.config。微软的指令也建议

    http://msdn.microsoft.com/en-us/library/vstudio/cc716677(v=vs.100).aspx

    【讨论】:

      猜你喜欢
      • 2017-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-28
      • 1970-01-01
      • 2014-04-20
      • 1970-01-01
      • 2014-11-22
      相关资源
      最近更新 更多