我使用ShoppingList 5 web应用模板(MVC 6/MVC核心/ASP.NET-5)制作了一个名为asp.net的示例web应用程序。我想用自定义字段名DefaultListId扩展用户配置文件。
ApplicationUser.cs:
namespace ShoppingList.Models
{
// Add profile data for application users by adding properties to the ApplicationUser class
public class ApplicationUser : IdentityUser
{
public int DefaultListId { get; set; }
}
}在家庭控制器中,我想访问为该属性存储的数据。我试过:
namespace ShoppingList.Controllers
{
public class HomeController : Controller
{
private UserManager<ApplicationUser> userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
public IActionResult Index()
{
var userId = User.GetUserId();
ApplicationUser user = userManager.FindById(userId);
ViewBag.UserId = userId;
ViewBag.DefaultListId = user.DefaultListId;
return View();
}
//other actions omitted for brevity但是,我得到以下错误:
严重程度代码描述项目文件行抑制状态错误-不存在与“C:\Users\OleKristian\Documents\Programmering\ShoppingList\src\ShoppingList\Controllers\HomeController.cs (IUserStore,IOptions,IPasswordHasher,IEnumerable>,IEnumerable>,ILookupNormalizer,IdentityErrorDescriber,IServiceProvider,ILogger>,IHttpContextAccessor) ShoppingList.DNX 4.5.1,ShoppingList.DNX Core 5.0 IPasswordHasher Active )所需的形式参数'optionsAccessor‘相对应的参数
还有..。
严重性代码描述项目文件行抑制状态错误CS1061 'UserManager‘不包含'FindById’的定义,也找不到接受'UserManager‘类型的第一个参数的扩展方法'FindById’(您缺少使用指令还是程序集引用?)C:\Users\OleKristian\Documents\Programmering\ShoppingList\src\ShoppingList\Controllers\HomeController.cs 20活动ShoppingList.DNX 4.5.1,ShoppingList.DNX Core5.0
发布于 2016-02-13 23:24:40
您不应该像以往一样实例化您自己的UserManager。实际上,这样做非常困难,因为它要求您将许多参数传递给构造函数(其中大多数事情也很难正确设置)。
ASP.NET Core广泛使用依赖项注入,因此您应该设置控制器,使其能够自动接收用户管理器。这样,您就不必担心创建用户管理器:
public class HomeController : Controller
{
private readonly UserManager<ApplicationUser> userManager;
public HomeController (UserManager<ApplicationUser> userManager)
{
this.userManager = userManager;
}
// …
}但是,为了做到这一点,您首先需要设置ASP.NET标识,以便真正了解您的ApplicationUser,并将其用于存储用户身份。为此,您需要修改Startup类。在ConfigureServices方法中,需要更改AddIdentity调用以使其引用实际类型:
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();这里的IdentityRole指的是ASP.NET标识所使用的标准角色类型(因为您不需要定制的角色类型)。正如您所看到的,我们还引用了一个ApplicationDbContext,它是修改后的身份模型的实体框架数据库上下文;因此,我们也需要设置该模型。在你的例子中,它可以是这样的:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// here you could adjust the mapping
}
}这将确保ApplicationUser实体实际上被正确地存储在数据库中。我们差不多完成了,但是现在我们只需要告诉有关数据库上下文的信息。因此,再次在ConfigureServices类的Startup方法中,确保调整AddEntityFramework调用以设置ApplicationDbContext数据库上下文。如果您有其他数据库上下文,则只需将以下内容链接:
services.AddEntityFramework()
.AddSqlServer()
.AddDbContext<IdentityContext>(opts => opts.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]))
.AddDbContext<DataContext>(opts => opts.UseSqlServer(Configuration["Data:DefaultConnection:ConnectionString"]));就这样!现在,实体框架知道了新的用户实体,并正确地将其映射到数据库(包括您的新属性),ASP.NET标识也知道您的用户模型,并将该模型用于它所做的一切,您可以将UserManager注入控制器(或服务或其他什么)中来执行任务。
至于第二个错误,这是因为用户管理器没有FindById方法;它只是作为一个FindByIdAsync方法。实际上,在许多使用ASP.NET核心的地方,您会看到只有异步方法,所以请接受它,并开始使您的方法也是异步的。
在您的示例中,您需要像这样更改Index方法:
// method is async and returns a Task
public async Task<IActionResult> Index()
{
var userId = User.GetUserId();
// call `FindByIdAsync` and await the result
ApplicationUser user = await userManager.FindByIdAsync(userId);
ViewBag.UserId = userId;
ViewBag.DefaultListId = user.DefaultListId;
return View();
}如您所见,使该方法异步不需要进行许多更改。大部分都是一样的。
https://stackoverflow.com/questions/35386237
复制相似问题