在 Blazor 服务器端 CRUD 应用程序中授权登录用户查看其特定数据(不是所有用户创建的所有数据)



问这个问题我感觉很糟糕,有点愚蠢,因为它对许多专家来说可能看起来很简单,但它让我无休止地工作了几天,而我的解决方案却无法正常工作,这有点令人沮丧。 任何帮助我摆脱这个通行证将不胜感激。代码链接位于本文末尾。 我只需要找出一种在 Blazor CRUD 应用程序中使用授权的方法,以便登录用户只能查看特定于他们的数据(由他们在登录后创建(。

项目是什么? 我创建了一个作业提醒列表(针对学生(,其中有一个子组件"作业详细信息"嵌套在名为"作业提醒列表"的父组件中。 子组件:具有启用输入数据(作为模态(的表单,并显示分配列表:

父组件代码的重要部分:

@if (assignmentList == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Assignments</th>
<th>Status</th>
<th>Due Date</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
@foreach (var assignment in assignmentList)
{
<tr>
<td>@assignment.Title</td>
<td>@assignment.Status</td>
<td>@assignment.DueDate</td>
<td><input type="button" class="btn btn-primary" @onclick="(()=>PrepareForEdit(assignment))" data-toggle="modal" data-target="#assignmentModal" value="Edit" /></td>
<td><input type="button" class="btn btn-primary" @onclick="(()=>PrepareForDelete(assignment))" data-toggle="modal" data-target="#confirmDeleteModal" value="Delete" /></td>
</tr>
}
</tbody>
</table>
}
<div>
<input type="button" data-toggle="modal" data-target="#assignmentModal" class="btn btn-primary" value="Add Task"
@onclick="(()=>InitializeAssignmentObject())" />
</div>
<ConfirmDelete OnClick="@Delete"></ConfirmDelete>
<AssignmentDetail AssignmentObject="assignmentObject" OnSave="@Refreshed">
<CustomHeader>@customHeader</CustomHeader>
</AssignmentDetail>

@code {
List<AssignmentReminder> assignmentList;
AssignmentReminder assignmentObject = new AssignmentReminder();
string customHeader = string.Empty;
private readonly ApplicationDbContext _db;

protected override async Task OnInitializedAsync()
{
assignmentList = await service.GetAssignments();
await GetUserDetails();
}
string Message = "";
public List<AssignmentReminder> AssignmentReminders { get; set; }

private async Task GetUserDetails()
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
//if (user.Identity.IsAuthenticated)
//{
var currentUser = await UserManager.GetUserAsync(user);
var currentUserId = currentUser.Id;
assignmentList = await _db.assignments.Where(a => a.OwnerID == currentUserId).ToListAsync();
}
} 

型号为:

public class AssignmentReminder
{
[Key]
public int Id { get; set; }
//User ID from AspNetUser table
public string OwnerID { get; set; }
[Required(ErrorMessage = "Assignment title is required")]
[StringLength(50, ErrorMessage = "Title is too long.")]
public string Title { get; set; }
[Required(ErrorMessage = "Status is required")]
public string Status { get; set; }
[Required(ErrorMessage = "Due Date is required")]
public DateTime DueDate { get; set; }
}  

现在的问题是,我创建的用于过滤和获取特定于用户的数据的 GetUserDetails(( 方法最终会出现运行时空引用异常,因为我无法在分配表中创建记录时填写 OwnerId(在赋值表中与 AspNetUser 表中的 userId 相同(。

项目可在以下位置获得:https://github.com/krchome/BlazorAssignmentReminder(适用于希望在最后尝试的任何人(

在我看来,问题是您在创建新记录时没有保存当前用户。

所以我添加了这个:

private async Task HandleValidSubmit()
{
if (AssignmentObject.Id == 0)
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
var currentUser = await UserManager.GetUserAsync(user);
var currentUserId = currentUser.Id;
AssignmentObject.OwnerID = currentUserId;
await service.AddAssignment(AssignmentObject);
}
else
{
await service.EditAssignment(AssignmentObject);
}
await CloseTaskModal();
//await HideInput();
// await ShowInput();
await OnSave.InvokeAsync(AssignmentObject);
// DataChanged?.Invoke();
}

我还添加了一个仅提取当前用户的记录的方法。

为了您的服务,我添加了以下内容:

public async Task<List<AssignmentReminder>> GetAssignmentsForUser(string OwnerID)
{
return await _context.assignments.Where(x => x.OwnerID == OwnerID).ToListAsync();
}

然后将父控件更改为:

@page "/taskreminder"
@using CRUDAppDemo.Data
@using CRUDAppDemo.Services
@using System.Data.Entity
@inject IAssignmentReminderService service
@inject IJSRuntime jsRuntime
@inject AuthenticationStateProvider AuthenticationStateProvider
@*@inject AssignmentReminderListAuthorization authorization*@
@using Microsoft.AspNetCore.Identity;
@using Microsoft.AspNetCore.Http;
@inject IHttpContextAccessor httpContextAccessor
@inject UserManager<IdentityUser> UserManager
@*@inject DI_BasePageModel di_page
@inject AssignmentReminderListAuthorization authorize*@
<h1>Assignment Reminder</h1>

@if (assignmentList == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Assignments</th>
<th>Status</th>
<th>Due Date</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
@foreach (var assignment in assignmentList)
{
<tr>
<td>@assignment.Title</td>
<td>@assignment.Status</td>
<td>@assignment.DueDate</td>
<td><input type="button" class="btn btn-primary" @onclick="(()=>PrepareForEdit(assignment))" data-toggle="modal" data-target="#assignmentModal" value="Edit" /></td>
<td><input type="button" class="btn btn-primary" @onclick="(()=>PrepareForDelete(assignment))" data-toggle="modal" data-target="#confirmDeleteModal" value="Delete" /></td>
</tr>
}
</tbody>
</table>
}
<div>
<input type="button" data-toggle="modal" data-target="#assignmentModal" class="btn btn-primary" value="Add Task"
@onclick="(()=>InitializeAssignmentObject())" />
</div>
<ConfirmDelete OnClick="@Delete"></ConfirmDelete>
<AssignmentDetail AssignmentObject="assignmentObject" OnSave="@GetUserDetails">
<CustomHeader>@customHeader</CustomHeader>
</AssignmentDetail>

@code {
List<AssignmentReminder> assignmentList;
AssignmentReminder assignmentObject = new AssignmentReminder();
string customHeader = string.Empty;
private readonly ApplicationDbContext _db;

protected override async Task OnInitializedAsync()
{
await GetUserDetails();
}
private void InitializeAssignmentObject()
{
assignmentObject = new AssignmentReminder();
assignmentObject.DueDate = DateTime.Now;
}
private void PrepareForEdit(AssignmentReminder assignmentReminder)
{
customHeader = "Edit Task";
assignmentObject = assignmentReminder;
}
private void PrepareForDelete(AssignmentReminder assignmentReminder)
{
assignmentObject = assignmentReminder;
}
private async Task Delete()
{
var task = await service.DeleteAssignment(assignmentObject.Id);
await jsRuntime.InvokeAsync<object>("HideModal", "confirmDeleteModal");
assignmentList = await service.GetAssignments();
assignmentObject = new AssignmentReminder();
}
//new code
string Message = "";
public List<AssignmentReminder> AssignmentReminders { get; set; }
private async Task GetUserDetails()
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
if (user.Identity.IsAuthenticated)
{
var currentUser = await UserManager.GetUserAsync(user);
var currentUserId = currentUser.Id;
assignmentList = await service.GetAssignmentsForUser(currentUserId);
}
}
}

最新更新