我使用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相关问答推荐

包含Include的低速EF核心查询

在 ASP.Net 中使用 Page_Load 和 Page_PreRender

如何从 dll 文件中提取类的源代码?

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

MSCharts找不到请求类型'GET'的http处理程序错误

无法访问,内部,资源文件?

如何在asp.net中判断会话是否过期

如何从 asp:Repeater 循环遍历项目模板中的项目?

如何使用 javascript 调用 ASP.NET c# 方法

以编程方式添加跨度标签,而不是标签控件?

如何在 ASP.NET 下拉列表中添加选项组?

ASP.NET IIS Web.config [内部服务器错误]

Owin.IAppBuilder不包含MapSignalR的定义

单击按钮时播放哔声

aspnet_compiler 发现错误版本的 System.Web.WebPages 1.0.0.0 而不是 2.0.0.0

ASP .NET 单例

ASP.NET:在 Response.Redirect(...) 之后代码会发生什么?

IIS url 重写角色,除了一些 url

可以在不 destruct 站点的情况下将 MIME 类型添加到 web.config 吗?

使用 jQuery 从 asp:RadioButtonList 读取选定的值