我使用Visual Studio 2013 Update 2创建了一个ASP.NET MVC 5应用程序.在应用程序中,我有一个帐户控制器.这跟我习惯的和不习惯的不一样 包含dbcontext的实例化.

public class AccountController : Controller
{
    private ApplicationUserManager _userManager;

    public AccountController()
    {
    }

    public AccountController(ApplicationUserManager userManager)
    {
        UserManager = userManager;
    }

    public ApplicationUserManager UserManager {
        get
        {
            return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
        private set
        {
            _userManager = value;
        }
    }

默认情况下创建的My web.config具有如下连接字符串:

  <connectionStrings>
    <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-WebApplication3-20140417072624.mdf;Initial Catalog=aspnet-WebApplication3-20140417072624;Integrated Security=True"
      providerName="System.Data.SqlClient" />
  </connectionStrings>

有人能向我解释一下,当应用程序第一次启动时,它是如何知道为这个应用程序创建数据库的?

此外,在随后的启动中,它是否使用实体框架访问标识表来进行身份验证?

推荐答案

1) WHAT'S GOING ON HERE:

当您创建一个新的MVC 5应用程序并 Select "Individual User Accounts"时,将包括一个使用Entity Framework 6 Code-First的新ASP.NET Identity Provider.

微软采用了EF-Code-First,使Identity尽可能可定制.

第一次访问Identity时,Entity Framework会判断数据库是否存在.除非另有配置,否则它使用"DefaultConnection"来查找标识数据库.如果在调用Identity时数据库不存在,EF会自动创建数据库.

请注意,您的连接字符串包含

`AttachDbFilename=|DataDirectory|\aspnet-WebApplication3-20140417072624.mdf`

如果你打开App_Data文件夹,你应该有一个aspnet-WebApplication3-20140417072624.mdf文件.

如果您双击此.mdf文件,VS2013 Server Explorer将打开您的数据库.如果您已try 访问任何身份功能,则将创建以下表:

  • _MigrationHistory
  • ASPNetRoles
  • ASPNetUserClaims
  • ASPNetUserLogins
  • ASPNetUsers

默认情况下,你的应用程序被配置为使用SQL Server Compact(MDF文件),因此你不必运行实际的SQL Server实例.所有这些都是可定制的.MDF文件的名称、标识数据库的模式、SQL Compact与实际SQL Server实例的 Select .更改连接字符串,或创建一个新字符串,并将此新连接传递给上下文.


2) WHERE IS MY CONTEXT?

所有这些都很好,但是您提出的一个重要问题基本上是"Where is my context?",以及关于如何进一步自定义数据库或更改验证逻辑的相关隐含问题.

您会注意到您的项目引用了Microsoft.AspNet.Identity.EntityFramework.此程序集是IdentityDBContext<TUser>的实现和UserManager类的实现.

打开AccountController,注意构造函数传递了UserManager个对象,然后又传递了new UserStore个对象,然后传递了ApplicationDbContext个对象.

    public AccountController()
        : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))

ApplicationDbContextModels文件夹中定义.在这个文件夹中,你会发现一个IdentityModels.cs文件.打开它,你就会看到

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection")
    {
    }
}

这是分配身份上下文的地方.您可以更改传递给ApplicationDbContext构造函数的连接名称,或者在帐户控制器中定义并使用不同的上下文.


3) HOW DO I CUSTOMIZE MY IDENTITY SCHEMA?

IdentityModels.cs文件中定义的另一个类是继承自IdentityUser类的ApplicationUser类.

public class ApplicationUser : IdentityUser
{
}

添加到此类的任何属性都将保留在ASPNetUsers表中.模式的其余部分在IdentityDbContext类中定义.因此,虽然您可以通过向上下文定义中添加DBSet向标识模式中添加更多表(例如特权),

public DBSet<Privileges> { get; set; }

更改其他表(角色、声明等)也是可能的,但要复杂得多.例如,要自定义Roles表,必须实现从IdentityRole继承的NewIdentityRole,并通过覆盖上下文的OnModelCreating()方法来添加它的关系.

关于100的这篇文章很好地描述了所涉及的步骤.即使在这里,您也会发现,简单地添加新列会带来很大的麻烦.从IdentityDbContext类中创建的原始模式中删除表或列可能与创建自己的IdentityDbContext类实现一样麻烦.

Asp.net相关问答推荐

更新剃须刀页面中图表的值

如何格式化搜索字符串以从 Razor 页表中的多个列返回部分搜索字符串?

无法连接到 ASP.Net 开发服务器问题

ASP.NET @Register 与 @Reference

Dotnet core 2.0 身份验证多模式身份 cookie 和 jwt

ASP.NET Web 应用程序 (.NET Framework) 与 ASP.NET Core Web 应用程序 (.NET Framework) 之间的差异

asp.net:与其中的用户控件相比,控件/页面的页面生命周期顺序是什么?

等待本地主机,永远!

无法让嵌套在 UpdatePanel 中的 WebControl 中的 ScriptManager.RegisterStartupScript 工作

ASP.NET MVC 5 中的路由可选参数

如何从 HTTP 请求中获取 MAC 地址?

Eval()、XPath() 和 Bind() 等数据绑定方法只能在数据绑定控件的上下文中使用

使下拉列表项不可 Select

根据 DropDownList 的值动态启用或禁用RequiredFieldValidator

HttpContext.Current 在 MVC 4 项目中未解决

OWIN 和 Katana,为什么要将应用程序与服务器解耦?

通过 CultureInfo 格式化字符串

ASP.NET MVC2/3 中runAllManagedModulesForAllRequests的正确用法是什么?

目录与目录信息

新的 csproj 文件 struct 可以与 ASP.NET Framework 项目一起使用吗?