2017-06-29 82 views
0

我已经将一些特定的属性添加到了标准项目的ApplicationUser。 一些添加的属性是自定义类。 因为我使用EntityFramework,它为用户创建一个dbtable,为每个自定义类创建一个。 我添加了属性到我的ManageController和视图,并将这些属性添加到特定的dbtable作品,但我无法访问它们。在dbo.AspNetUsers中添加了一列,在属性+ ID(在我的示例“NameID”)后调用。.Net Core获取ApplicationUser的对象

现在,如果我在我的ManageController中加载用户,则会加载每个普通属性,但自定义属性为空。

我的问题是,我如何加载自定义对象(真的存储在另一个表中)。

ApplicationUser.cs:

namespace refProject.Models 
{ 
    public class ApplicationUser : IdentityUser 
    { 
     public Name Name { get; set; } 
    } 
} 

ManageController.cs

//other usings 
using refProject.Models; 
using refProject.Models.ManageViewModels; 

namespace refProject.Controllers 
{ 
    [Authorize] 
    public class ManageController : Controller 
    { 
     private readonly UserManager<ApplicationUser> _userManager; 
     //other managers 

     public ManageController(
      UserManager<ApplicationUser> userManager, 
      //other managers 
     ) 
     { 
      _userManager = userManager; 
      //other managers 
     } 

     // 
     // GET: /Manage/Index 
     [HttpGet] 
     public async Task<IActionResult> Index(ManageMessageId? message = null) 
     { 
      ViewData["StatusMessage"] = 
       message == ManageMessageId.ChangeNameSuccess ? "Your name has been changed." 
       : message == ManageMessageId.SetNameSuccess ? "Your name has been set." 
       : ""; 

      var user = await GetCurrentUserAsync(); 
      if (user == null) 
      { 
       return View("Error"); 
      } 
      var model = new IndexViewModel 
      { 
       //other Properties 
       // 
       // 
       // THIS ONE IS NULL 
       // 
       //   
       Name = user.Name 
       //other Properties 
      }; 
      return View(model); 
     } 

     // GET: /Manage/ChangeName 
     [HttpGet] 
     public IActionResult ChangeName() 
     { 
      return View(); 
     } 

     // 
     // POST: /Manage/ChangeName 
     [HttpPost] 
     [ValidateAntiForgeryToken] 
     public async Task<IActionResult> ChangeName(ChangeNameViewModel model) 
     { 
      if(!ModelState.IsValid) 
      { 
       return View(model); 
      } 
      var user = await GetCurrentUserAsync(); 
      if(user != null) 
      { 
       Name NewName = new Name(); 
       NewName.FirstName = model.NewFirstName; 
       NewName.LastName = model.NewLastName; 

       user.Name = NewName; 

       IdentityResult result = await _userManager.UpdateAsync(user); 
       if (result.Succeeded) 
       { 
        return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ChangeNameSuccess }); 
       } 
       AddErrors(result); 
       return View(model); 
      } 
      return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error }); 
     } 

     // 
     // GET: /Manage/SetName 
     [HttpGet] 
     public IActionResult SetName() 
     { 
      return View(); 
     } 

     // 
     // POST: /Manage/SetName 
     [HttpPost] 
     [ValidateAntiForgeryToken] 
     public async Task<IActionResult> SetName(SetNameViewModel model) 
     { 
      if(!ModelState.IsValid) 
      { 
       return View(model); 
      } 

      var user = await GetCurrentUserAsync(); 
      if(user != null) 
      { 
       Name NewName = new Name(); 
       NewName.FirstName = model.NewFirstName; 
       NewName.LastName = model.NewLastName; 

       user.Name = NewName; 

       IdentityResult result = await _userManager.UpdateAsync(user); 
       if(result.Succeeded) 
       { 
        return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetNameSuccess }); 
       } 
       AddErrors(result); 
       return View(model); 
      } 
      return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error }); 
     } 

     #region Helpers 

     private void AddErrors(IdentityResult result) 
     { 
      foreach (var error in result.Errors) 
      { 
       ModelState.AddModelError(string.Empty, error.Description); 
      } 
     } 

     public enum ManageMessageId 
     { 
      Error, 
      ChangeNameSuccess, 
      SetNameSuccess, 
     } 

     private Task<ApplicationUser> GetCurrentUserAsync() 
     { 
      return _userManager.GetUserAsync(HttpContext.User); 
     } 

     #endregion 
    } 
} 

Name.cs

namespace refProject.Models 
{ 
    public class Name 
    { 
     public int ID { get; set; } 
     public string fTitle { get; set; } 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public string lTitle { get; set; } 

     public override string ToString() 
     { 
      return fTitle + " " + FirstName + " " + LastName + " " + lTitle; 
     } 
    } 
} 
+1

您正在使用非标准的条款。属性=属性? – Tseng

回答

3

这是一个已知的问题。这不是一个错误,而是一个设计决定。

推荐的方法是通过DbContext而不是从UserManager实现来访问用户。

“只需添加更多的细节:作为性能优化ASP.NET Core Identity当前仅根据需要加载与用户或角色相关的实体以满足API调用,即它不会加载相关实体(甚至没有内置的)急切地像如FindByName()因为查找方法只需要返回根的方法调用。

此时发出查询对DbContext是推荐 方式来加载如果你想从 应用程序代码中抽象出来,你可以扩展身份存储和管理器 cla sses to add methods to retrieve and returns your custom related data。“

Comment link

你可以改变你GetCurrentUserAsync方法如下:

private ApplicationUser GetCurrentUserAsync() 
{ 
    return _userManager.Users.Include(x => x.Name).FirstOrDefault(x => x.Id == _userManager.GetUserId(User)); 
}