2017-06-29 60 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)); 
}