什么将ApplicationUser绑定到Database First中的aspnetusers表?

时间:2015-01-27 22:21:44

标签: c# asp.net-mvc entity-framework-6 asp.net-identity ef-database-first

我在一个单独的库(例如Common.Feedback.Data)中有一个数据库优先的EDMX模型,其中包括AspNetUser表及其相关的Identity Framework表(从另一个现有的,工作的,数据库/应用程序中提取) )。

我已更新ApplicationDbContext连接字符串以指向新模型和新数据库连接:

using System.Data.Entity;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;

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

    public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }
    }

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()
            : base("FeedbackEntities", throwIfV1Schema: false)
        {
        }

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

web.config中的连接字符串包含程序集的完整路径,该引用很好:

<add name="FeedbackEntities" 
     connectionString="metadata=res://Common.Feedback.Data/FeedbackModel.csdl|res://Common.Feedback.Data/FeedbackModel.ssdl|res://Common.Feedback.Data/FeedbackModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=mydatabase.database.windows.net;initial catalog=Feedback;persist security info=True;user id=LeaveFeedbackuser@mydatabase;password=mypassword;MultipleActiveResultSets=True;App=EntityFramework&quot;" 
     providerName="System.Data.EntityClient" />

在运行时,对登录的任何访问都会导致以下错误:

  

&#34;实体类型ApplicationUser不是当前上下文模型的一部分&#34;

我尝试过的与该错误相关的所有链接通常都涉及更新迁移的方法。

我无法启用迁移,因为它是EDMX的首次设置,但我认为ApplicationUser对象和aspnetusers表之间存在绑定&#34;某处&#34;在幕后。

这里有没有人清楚地了解ApplicationUser类在运行时如何映射到aspnetusers表/来自Common.Feedback.Data表,并解释如何让我的代码与数据库一起使用?

重新执行

  • 使用VS 2013
  • 创建新的MVC Web应用程序
  • 将所有NuGet包更新为最新
  • 使用Identity Framework表获取现有SQL数据库并将其复制到新表(删除任何不相关的表)。
  • 为项目添加新表
  • 创建一个类库来保存数据模型(例如res://*/
  • 根据之前创建的数据库
  • 将Edmx数据模型添加到库中
  • 更改连接字符串以完全限定程序集(不是IdentityModel.cs
  • 更改app.config中的连接字符串名称以匹配配置中的连接字符串名称。
  • 将图书馆的web.config中的连接字符串复制到网络项目<add name="FeedbackSql" connectionString="data source=mydatabase.database.windows.net;initial catalog=Feedback;persist security info=True;user id=LeaveFeedbackuser@mydatabase;password=mypassword;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
  • 尝试登录,您将遇到提及的错误

更新

基于一个迷路邮件,我更改了我的连接字符串,以匹配Identity Framework默认配置使用的正常SQL连接(并使用Sql客户端):

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

并更改为设置以使用此新连接:

  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
      <parameters>
        <!--<parameter value="mssqllocaldb" />-->
        <parameter value="data source=mydatabase.database.windows.net;initial catalog=Feedback;persist security info=True;user id=myuserid;password=mypassword;MultipleActiveResultSets=True;App=EntityFramework" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>

奇怪的是,错误变为:

  

GZip标头中的幻数不正确。确保传入GZip流。

我认为对SqlClient提供程序的初始更改是正确的,因此这个新错误可能与通过该连接使用Azure数据库有关。我愿意接受下一步尝试的建议。

根据@rism和this link的建议更新了web.config(但GZip错误仍然存​​在):

  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v12.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>

再次基于@rism的提示我也试过这个版本(但GZip错误仍然存​​在):

  <connectionStrings>
    <add name="DefaultConnection" 
         connectionString="data source=mydatabase.database.windows.net;initial catalog=Feedback;persist security info=True;user id=LeaveFeedbackuser;password=mypassword;MultipleActiveResultSets=True;App=EntityFramework"
         providerName="System.Data.SqlClient" />
  </connectionStrings>

新更新:

我使用标准的 user-security 选项创建了一个全新的Web应用程序。我还在Azure中创建了一个空数据库。

我什么也没做,只是将默认连接字符串更改为:

  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v12.0" />
      </parameters>
    </defaultConnectionFactory>
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>

和默认的连接工厂:

{{1}}

尝试登录时出现以下错误:

  

GZip标头中的幻数不正确。确保你是   传入GZip流。描述:未处理的异常   在执行当前Web请求期间发生。请   查看堆栈跟踪以获取有关错误和位置的更多信息   它起源于代码。

     

异常详细信息:System.IO.InvalidDataException:幻数   在GZip标题中不正确。确保你传递的是GZip   流。

     

来源错误:

     

第153行:{第154行:var user = new   ApplicationUser {UserName = model.Email,Email = model.Email};线   155:var result = await UserManager.CreateAsync(user,   model.Password);第156行:if(result.Succeeded)行   157:{

1 个答案:

答案 0 :(得分:11)

最初的问题是OWIN如何将ApplicationUser类映射到AspNetUsers表。

我用DotPeek反编译了Identity Framework dll,发现表名&#34; AspNetUsers&#34;只是简单地连接到OnModelCreating方法的代码中。 e.g。

 protected virtual void OnModelCreating(DbModelBuilder modelBuilder)
    {
      if (modelBuilder == null)
        throw new ArgumentNullException("modelBuilder");
        EntityTypeConfiguration<TUser> typeConfiguration1 = ((EntityTypeConfiguration<TUser>) modelBuilder.Entity<TUser>())
        .ToTable("AspNetUsers");

该代码使用反射从ApplicationUser中的属性生成字段名称列表。它使用简单的SQL查询(包含所有字段名称的系统表)检查所有这些字段名称是否存在,并确认它们都存在。

其余的是使用构造的SQL查询对名称/值进行简单映射。

至于问题的另一部分,数据库连接,我创建了一个新问题,因为它是a)与这个标题无关,b)让我发疯!新的问题是Why am I getting "The magic number in GZip header is not correct." error using OWIN auth against Azure SQL