c# - .Net Core获取ApplicationUser的对象

标签 c# entity-framework asp.net-core asp.net-core-mvc

我已向标准项目的 ApplicationUser 添加了一些特定属性。 一些添加的属性属于自定义类。 由于我使用 EntityFramework,它为用户创建一个 dbtable,并为每个自定义类创建一个 dbtable。 我将属性添加到我的 ManageController 和 View 中,并将这些属性添加到特定的 dbtable 中,但我无法访问它们。在 dbo.AspNetUsers 中添加了一列,在属性 + ID 之后调用(在我的示例中为“NameID”)。

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

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

ApplicationUser.cs:

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

管理 Controller .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
    }
}

名称.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;
        }
    }
}

最佳答案

这是一个已知问题。它不被视为错误,而是设计决策。

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

"Just to add a bit more detail: as a performance optimization ASP.NET Core Identity currently only loads the entities related to a user or a role as needed to satisfy API calls. I.e. it won't load related entities (not even the built-in ones) eagerly on a method call like such as FindByName() because the find methods are only required to return the root.

At this point issuing queries against the DbContext is the recommended way to load related data. If you want to abstract this from the application code you can extend both the Identity store and manager classes to add methods to retrieve and return your custom related data."

Comment link

您可以按如下方式更改 GetCurrentUserAsync 方法:

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

关于c# - .Net Core获取ApplicationUser的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44833245/

相关文章:

c# - 通过依赖注入(inject)获取连接字符串

c# - JSON 序列化器 - 当前端缺少设置为 false 的 bool 值时

c# - 显式实现接口(interface)的一些方法,隐式实现一些方法

c# - 错误包管理器控制台

c# - 带字符串的随机数生成器

C#/ASP.NET MVC3,从 DateTime.UtcNow 转换为客户端的时区。如何获取时区信息?

c# - Entity Framework 如何使用递归层次结构? Include() 似乎不适用于它

c# - Entity Framework 代码优先外键问题

c# - 如何记录谓词表达式?

asp.net-core - ASP.NET Core 无法创建根证书