将 ASP.NET 核心身份用户属性保存在另一个表中
Posted
技术标签:
【中文标题】将 ASP.NET 核心身份用户属性保存在另一个表中【英文标题】:Save ASP.NET core Identity User attributes in another table 【发布时间】:2021-03-15 07:14:05 【问题描述】:我正在开发一个 ASP .NET 核心 Web 应用程序。我使用 Identity UI 框架 在应用程序中进行用户注册和授权。我将身份用户继承到我的ApplicationUser
类,如下所示。它创建了一个名为ApplicationUser
的表,并成功保存了给定属性下的相关数据:(我使用的是Microsoft SQL
数据库)
ApplicationUser.cs
using Microsoft.AspNetCore.Identity;
using System;
using System.Collections.Generic;
#nullable disable
namespace WebApp.Models
public partial class ApplicationUser : IdentityUser<int>
public ApplicationUser()
public string FirstName get; set;
public string MiddleName get; set;
public string LastNam get; set;
public DateTime? DateOfBirth get; set;
public string Bio get; set;
public virtual UserAddress UserAddress get; set;
然后我实现UserAddress
模型类如下。它在数据库中创建另一个名为 "UserAddress"\
UserAddress.cs
using System;
using System.Collections.Generic;
#nullable disable
namespace WebApp.Models
public partial class UserAddress
public int UserId get; set;
public string BuildingNo get; set;
public string Street get; set;
public string City get; set;
public string State get; set;
public string ZipCode get; set;
public virtual ApplicationUser User get; set;
接下来在 Identity UI 框架的 Areas 文件夹下,我将 Index.cshtml 文件更改如下。我插入新条目以输入用户的building number
,该条目应保存在数据库中的UserAddress
表中。
Index.cshtml
@page
@model IndexModel
@
ViewData["Title"] = "Profile";
ViewData["ActivePage"] = ManageNavPages.Index;
<h4>@ViewData["Title"]</h4>
<partial name="_StatusMessage" model="Model.StatusMessage" />
<div class="row">
<div class="col-md-12">
<form id="profile-form" method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="=row d-flex flex-row">
<div class="form-group col-md-6">
<label asp-for="Input.UserName"></label>
<input asp-for="Input.UserName" class="form-control" />
</div>
</div>
<div class="=row d-flex flex-row">
<div class="form-group col-md-6">
<label asp-for="Input.FirstName"></label>
<input asp-for="Input.FirstName" class="form-control" />
</div>
<div class="form-group col-md-6">
<label asp-for="Input.MiddleName"></label>
<input asp-for="Input.MiddleName" class="form-control" />
</div>
</div>
<div class="=row d-flex flex-row">
<div class="form-group col-md-6">
<label asp-for="Input.LastNam"></label>
<input asp-for="Input.LastNam" class="form-control" />
</div>
</div>
<div class="=row d-flex flex-row">
<div class="form-group col-md-6">
<label asp-for="Input.DateOfBirth"></label>
<input asp-for="Input.DateOfBirth" class="form-control" />
</div>
<div class="form-group col-md-6">
<label asp-for="Input.PhoneNumber"></label>
<input asp-for="Input.PhoneNumber" class="form-control" />
<span asp-validation-for="Input.PhoneNumber" class="text-danger"></span>
</div>
</div>
<div class="=row d-flex flex-row">
<div class="form-group col-md-6">
<label asp-for="Input.BuildingNo"></label>
<input asp-for="Input.BuildingNo" class="form-control" />
</div>
</div>
<div class="=row d-flex flex-row">
<div class="do-md-6">
<button id="update-profile-button" type="submit" class="btn btn-primary">Save</button>
</div>
</div>
</form>
</div>
</div>
@section Scripts
<partial name="_ValidationScriptsPartial" />
并且在Index.cshtml.cs文件中,我尝试将building number
保存在UserAddress
表中,如下所示,但无法将数据输入到表中。
Index.cshtml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using WebApp.Models;
namespace WebApp.Areas.Identity.Pages.Account.Manage
public partial class IndexModel : PageModel
private readonly UserManager<ApplicationUser> _userManager;
private readonly SignInManager<ApplicationUser> _signInManager;
public IndexModel(
UserManager<ApplicationUser> userManager,
SignInManager<ApplicationUser> signInManager)
_userManager = userManager;
_signInManager = signInManager;
public string BuildingNo get; set;
public string Username get; set;
[TempData]
public string StatusMessage get; set;
[BindProperty]
public InputModel Input get; set;
public class InputModel
[DataType(DataType.Text)]
[Display(Name = "User Name")]
public string UserName get; set;
[DataType(DataType.Text)]
[Display(Name = "First name")]
public string FirstName get; set;
[DataType(DataType.Text)]
[Display(Name = "Middle name")]
public string MiddleName get; set;
[DataType(DataType.Text)]
[Display(Name = "Last name")]
public string LastNam get; set;
[Display(Name = "Date of Birth")]
[DataType(DataType.Date)]
public DateTime DateOfBirth get; set;
[Phone]
[Display(Name = "Phone number")]
public string PhoneNumber get; set;
[Display(Name = "Building No:")]
[DataType(DataType.Text)]
public string BuildingNo get; set;
private async Task LoadAsync(ApplicationUser user)
var userName = await _userManager.GetUserNameAsync(user);
var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
Username = userName;
Input = new InputModel
UserName = user.UserName,
FirstName = user.FirstName,
MiddleName = user.MiddleName,
LastNam = user.LastNam,
PhoneNumber = phoneNumber,
;
public async Task<IActionResult> OnGetAsync()
var user = await _userManager.GetUserAsync(User);
if (user == null)
return NotFound($"Unable to load user with ID '_userManager.GetUserId(User)'.");
await LoadAsync(user);
return Page();
public async Task<IActionResult> OnPostAsync()
var user = await _userManager.GetUserAsync(User);
if (user == null)
return NotFound($"Unable to load user with ID '_userManager.GetUserId(User)'.");
if (!ModelState.IsValid)
await LoadAsync(user);
return Page();
var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
if (Input.PhoneNumber != phoneNumber)
var setPhoneResult = await _userManager.SetPhoneNumberAsync(user, Input.PhoneNumber);
if (!setPhoneResult.Succeeded)
StatusMessage = "Unexpected error when trying to set phone number.";
return RedirectToPage();
if(Input.FirstName != user.FirstName)
user.FirstName = Input.FirstName;
if (Input.MiddleName != user.MiddleName)
user.MiddleName = Input.MiddleName;
if (Input.LastNam != user.LastNam)
user.LastNam = Input.LastNam;
if (Input.DateOfBirth != user.DateOfBirth)
user.DateOfBirth = Input.DateOfBirth;
if (Input.UserName != user.UserName)
user.UserName = Input.UserName;
user.UserAddress.BuildingNo = Input.BuildingNo; // I tried to enter the building address to the UserAddress table by using this code
await _userManager.UpdateAsync(user);
await _signInManager.RefreshSignInAsync(user);
StatusMessage = "Your profile has been updated";
return RedirectToPage();
请忽略上面我提供的冗长的Index.cshtml.cs
代码,我在我用来将输入building number
插入到 UserAddress 表的唯一代码附近进行了评论。即:user.UserAddress.BuildingNo = Input.BuildingNo;
这是条目视图的一部分: The entry view这是我在运行上述代码时遇到的错误: The error message
记录:ApplicationUser
表中的所有字段都已更新。但是当我尝试将数据插入UserAddress
表时会发生此错误。
我是漂亮的用户,对于一个非常了解 ASP.NET 核心身份用户的人来说,这是一个非常简单的问题。
如果有人可以帮我将输入 building number
保存在另一个名为 User Address
的表中,我请您帮忙?
提前致谢!!!
【问题讨论】:
能否请您检查您的user
对象,是否有UserAddress
?如果它有 NULL,你不能赋值。你应该这样做```new UserAddress () BuildingNo = Input.BuildingNo;
【参考方案1】:
您可以像下面这样更改您的代码:
第一次使用代码获取当前user
包括UserAddress
:
var user = await _userManager.Users
.Include(x => x.UserAddress)
.SingleAsync(x => x.UserName== Input.UserName);
然后判断UserAddress
是否存在并更新。
if (user.UserAddress == null)
user.UserAddress = new Models.UserAddress
BuildingNo = Input.BuildingNo
;
else
user.UserAddress.BuildingNo = Input.BuildingNo;
整个代码如下:
public async Task<IActionResult> OnPostAsync()
//get the current user
var user = await _userManager.Users
.Include(x => x.UserAddress)
.SingleAsync(x => x.UserName== Input.UserName);
if (user == null)
return NotFound($"Unable to load user with ID '_userManager.GetUserId(User)'.");
if (!ModelState.IsValid)
await LoadAsync(user);
return Page();
var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
if (Input.PhoneNumber != phoneNumber)
var setPhoneResult = await _userManager.SetPhoneNumberAsync(user, Input.PhoneNumber);
if (!setPhoneResult.Succeeded)
StatusMessage = "Unexpected error when trying to set phone number.";
return RedirectToPage();
if(Input.FirstName != user.FirstName)
user.FirstName = Input.FirstName;
if (Input.MiddleName != user.MiddleName)
user.MiddleName = Input.MiddleName;
if (Input.LastNam != user.LastNam)
user.LastNam = Input.LastNam;
if (Input.DateOfBirth != user.DateOfBirth)
user.DateOfBirth = Input.DateOfBirth;
if (Input.UserName != user.UserName)
user.UserName = Input.UserName;
//insert the BuildingNo
if (user.UserAddress == null)
user.UserAddress = new Models.UserAddress
BuildingNo = Input.BuildingNo
;
else
user.UserAddress.BuildingNo = Input.BuildingNo;
await _userManager.UpdateAsync(user);
await _signInManager.RefreshSignInAsync(user);
StatusMessage = "Your profile has been updated";
return RedirectToPage();
【讨论】:
我会检查你的代码,让你知道它在工作的天气。非常感谢您的回答。以上是关于将 ASP.NET 核心身份用户属性保存在另一个表中的主要内容,如果未能解决你的问题,请参考以下文章
Missed User 属性,用于计算 asp.net 核心身份中的用户/角色数
控制器 ASP.net 核心 2.1 中的 Jwt 角色身份验证
在 asp.net 核心中使用身份时未找到具有授权属性的操作