在ASP.NET Core MVC中如何仅展示当前登录用户创建的数据条目
实现方案
步骤1:扩展Identity用户模型,建立一对多关联
你可以直接扩展默认AspNetUsers表对应的ApplicationUser实体类,添加和Item的一对多导航属性:
// 一般位于项目Areas/Identity/Data目录下的ApplicationUser.cs using Microsoft.AspNetCore.Identity; using System.Collections.Generic; public class ApplicationUser : IdentityUser { // 导航属性:一个用户对应多个自己创建的Item条目 public ICollection<Item> Items { get; set; } }
步骤2:修改Item模型,添加用户外键
给Item类新增关联用户的外键字段和导航属性:
public class Item { public int Id { get; set; } public string Name { get; set; } public string Description { get; set; } public string Power { get; set; } public string Charges { get; set; } // 新增:创建该条目的用户ID,外键关联AspNetUsers表的Id字段 public string UserId { get; set; } // 导航属性:一个Item仅属于一个创建用户 public ApplicationUser User { get; set; } public Item(){ } }
步骤3:同步更新数据库结构
在程序包管理器控制台依次执行以下命令,生成迁移脚本并更新数据库,会自动给Items表添加UserId外键约束:
Add-Migration AddItemUserRelation Update-Database
步骤4:调整Items控制器逻辑
首先给控制器引入所需命名空间:
using System.Security.Claims; using Microsoft.AspNetCore.Authorization;
4.1 全局添加登录校验(推荐)
如果所有Item相关操作都需要登录后才能访问,可以直接给控制器类添加[Authorize]特性,无需逐个给Action加:
[Authorize] public class ItemsController : Controller { // 原有代码 }
4.2 新增条目时自动绑定创建用户ID
修改Create的Post提交方法,保存数据前自动赋值当前登录用户的ID:
[HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create([Bind("Id,Name,Description,Power,Charges")] Item item) { if (ModelState.IsValid) { // 获取当前登录用户的唯一ID var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); item.UserId = userId; _context.Add(item); await _context.SaveChangesAsync(); return RedirectToAction(nameof(Index)); } return View(item); }
4.3 所有查询操作添加用户过滤
所有读取、修改、删除的逻辑都要增加校验,仅允许操作当前登录用户自己创建的条目:
- 调整列表查询:
// GET: Items public async Task<IActionResult> Index() { var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); return View(await _context.Item.Where(i => i.UserId == userId).ToListAsync()); }
- 调整搜索查询:
public async Task<IActionResult> ShowSearchResults(String SearchPhrase) { var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); return View("Index", await _context.Item .Where(j => j.UserId == userId && j.Name.Contains(SearchPhrase)) .ToListAsync()); }
- 调整详情、编辑、删除逻辑:
// GET: Items/Details/5 public async Task<IActionResult> Details(int? id) { if (id == null) { return NotFound(); } var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); var item = await _context.Item .FirstOrDefaultAsync(m => m.Id == id && m.UserId == userId); if (item == null) { return NotFound(); } return View(item); } // GET: Items/Edit/5 public async Task<IActionResult> Edit(int? id) { if (id == null) { return NotFound(); } var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); var item = await _context.Item.FirstOrDefaultAsync(i => i.Id == id && i.UserId == userId); if (item == null) { return NotFound(); } return View(item); } // POST: Items/Edit/5 [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Edit(int id, [Bind("Id,Name,Description,Power,Charges,UserId")] Item item) { if (id != item.Id) { return NotFound(); } var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); if (item.UserId != userId) { return NotFound(); } if (ModelState.IsValid) { try { _context.Update(item); await _context.SaveChangesAsync(); } catch (DbUpdateConcurrencyException) { if (!ItemExists(item.Id)) { return NotFound(); } else { throw; } } return RedirectToAction(nameof(Index)); } return View(item); } // GET: Items/Delete/5 public async Task<IActionResult> Delete(int? id) { if (id == null) { return NotFound(); } var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); var item = await _context.Item .FirstOrDefaultAsync(m => m.Id == id && m.UserId == userId); if (item == null) { return NotFound(); } return View(item); } // POST: Items/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public async Task<IActionResult> DeleteConfirmed(int id) { var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); var item = await _context.Item.FirstOrDefaultAsync(i => i.Id == id && i.UserId == userId); if (item != null) { _context.Item.Remove(item); await _context.SaveChangesAsync(); } return RedirectToAction(nameof(Index)); }
内容的提问来源于stack exchange,提问作者Age Co.
相关产品推荐
相关产品推荐

