我使用asp.net 5 Web应用程序模板(Mvc6 / MVC core / Asp.net-5)制作了一个名为ShoppingList的示例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
但是我收到以下错误:
严重级代码描述项目文件行抑制状态 错误CS7036没有给出对应的参数 需要形式参数'optionsAccessor' “UserManager.UserManager(IUserStore, IOptions,IPasswordHasher, IEnumerable的&gt;中 IEnumerable&gt;,ILookupNormalizer, IdentityErrorDescriber,IServiceProvider, ILogger&gt;中 'IHttpContextAccessor)'ShoppingList.DNX 4.5.1,ShoppingList.DNX Core 5.0 C:\ Users \ OleKristian \ Documents \ Programmering \ ShoppingList \ src \ ShoppingList \ Controllers \ HomeController.cs 15 Active
和...
严重级代码描述项目文件行抑制状态 错误CS1061'UserManager'不包含 'FindById'的定义,没有扩展方法'FindById'接受 可以找到“UserManager”类型的第一个参数 (你错过了使用指令或程序集吗? 参考?)ShoppingList.DNX 4.5.1,ShoppingList.DNX Core 5.0 C:\ Users \ OleKristian \ Documents \ Programmering \ ShoppingList \ src \ ShoppingList \ Controllers \ HomeController.cs 20 Active
答案 0 :(得分:5)
您不应该像往常一样实例化自己的UserManager
。实际上很难这样做,因为它要求你将许多参数传递给构造函数(而且大多数事情也很难正确设置)。
ASP.NET Core广泛使用依赖注入,因此您应该以自动接收用户管理器的方式设置控制器。这样,您就不必担心创建用户管理器了:
public class HomeController : Controller
{
private readonly UserManager<ApplicationUser> userManager;
public HomeController (UserManager<ApplicationUser> userManager)
{
this.userManager = userManager;
}
// …
}
但是,为了做到这一点,您首先需要设置ASP.NET Identity以实际了解您的ApplicationUser
并使其用于来存储您的用户身份。为此,您需要修改Startup
类。在ConfigureServices
方法中,您需要更改AddIdentity
调用以使其引用您的实际类型:
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
IdentityRole
这里指的是ASP.NET Identity使用的标准角色类型(因为您不需要自定义角色类型)。如您所见,我们还引用了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"]));
就是这样!现在,Entity Framework了解新的用户实体并将其正确映射到数据库(包括您的新属性),ASP.NET Identity也知道您的用户模型,并将其用于所做的一切,您可以拥有{ {1}}注入控制器(或服务,或其他)做事。
至于你的第二个错误,你得到这个,因为用户管理器没有UserManager
方法;它仅作为FindById
方法。实际上,在ASP.NET Core的许多地方都会看到这种情况,只有异步方法,所以请接受它并开始使你的方法异步。
在您的情况下,您需要更改FindByIdAsync
方法,如下所示:
Index
如您所见,它不需要很多更改就可以使方法异步。大多数都保持不变。