如何仅在 ASP.NET MVC 中仅显示当前登录用户创建的项目

Posted

技术标签:

【中文标题】如何仅在 ASP.NET MVC 中仅显示当前登录用户创建的项目【英文标题】:How to only display items created by the current logged in user only in ASP.NET MVC 【发布时间】:2021-10-29 10:14:03 【问题描述】:

正如问题所说,我正试图弄清楚我将如何做到这一点,因此当用户登录时,他们只会看到他们输入数据库的数据条目。我使用 ASP.NET Core Web App (Model-View_Controller) 模板启动。

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; 

    public Item()

       

    


这是有问题的数据,项目模型。我最初的想法是我需要在 AspNetUsers 表和 Items 表之间建立一对多的关系,然后在 items 控制器中更改某些内容,但我不完全确定如何/是否可以对 AspNetUsers 表进行编辑。

public class ItemsController : Controller

    private readonly ApplicationDbContext _context;

    public ItemsController(ApplicationDbContext context)
    
        _context = context;
    

    // GET: Items
    public async Task<IActionResult> Index()
    
        //Return a list to the view
        return View(await _context.Item.ToListAsync());
    

    public async Task<IActionResult> SearchItems()
    
        return View();
    

    public async Task<IActionResult> ShowSearchResults(String SearchPhrase)
    
        //Return a list from index where 
        return View("Index", await _context.Item.Where(j => j.Name.Contains(SearchPhrase)).ToListAsync());
    

    // GET: Items/Details/5
    public async Task<IActionResult> Details(int? id)
    
        if (id == null)
        
            return NotFound();
        

        var item = await _context.Item
            .FirstOrDefaultAsync(m => m.Id == id);
        if (item == null)
        
            return NotFound();
        

        return View(item);
    

    // GET: Items/Create
    [Authorize]
    public IActionResult Create()
    
        return View();
    

    // POST: Items/Create
    // To protect from overposting attacks, enable the specific properties you want to bind to, for 
    // more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
    [Authorize]
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create([Bind("Id,Name,Description,Power,Charges")] Item item)
    
        if (ModelState.IsValid)
        
            _context.Add(item);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        
        return View(item);
    

    // GET: Items/Edit/5
    [Authorize]
    public async Task<IActionResult> Edit(int? id)
    
        if (id == null)
        
            return NotFound();
        

        var item = await _context.Item.FindAsync(id);
        if (item == null)
        
            return NotFound();
        
        return View(item);
    

    // POST: Items/Edit/5
    // To protect from overposting attacks, enable the specific properties you want to bind to, for 
    // more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
    [Authorize]
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Edit(int id, [Bind("Id,Name,Description,Power,Charges")] Item item)
    
        if (id != item.Id)
        
            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
    [Authorize]
    public async Task<IActionResult> Delete(int? id)
    
        if (id == null)
        
            return NotFound();
        

        var item = await _context.Item
            .FirstOrDefaultAsync(m => m.Id == id);
        if (item == null)
        
            return NotFound();
        

        return View(item);
    

    // POST: Items/Delete/5
    [Authorize]
    [HttpPost, ActionName("Delete")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> DeleteConfirmed(int id)
    
        var item = await _context.Item.FindAsync(id);
        _context.Item.Remove(item);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    

    private bool ItemExists(int id)
    
        return _context.Item.Any(e => e.Id == id);
    

这是项目控制器。如果我需要提供更多信息,我可以。

【问题讨论】:

为什么需要修改 AspNetUsers 表?每个项目只能由一个用户拥有,对吗?因此,您的 item 表需要一个 UserId 列,该列是返回 AspNetUsers 表的外键引用。 你应该一次解决这件事。你说的是什么观点? Index 视图?如果是这样,请不要发布所有更新/创建/删除方法,它们只会混淆这一点。目前,Index 控制器操作似乎正在返回Item 表中的所有记录。您需要找出当前用户,然后查询该表以仅返回该用户的记录。 步骤应该是,首先,当你创建item时,它还应该记录created_by,它应该是一个userId。其次,一旦用户登录,您应该拥有user login id,然后调用一个项目列表,其中created_by 等于您登录的userId 【参考方案1】:

但我不完全确定如何/是否可以对 AspNetUsers 表进行编辑。

您可以从IdentityUser 继承自定义用户数据。

这是一个您可以关注的工作演示:

型号:

public class ApplicationUser:IdentityUser

    public List<Item> Items  get; set; 

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; 
    public ApplicationUser ApplicationUser  get; set; 

控制器:

public class ItemsController : Controller

    private readonly ApplicationDbContext _context;

    public ItemsController(ApplicationDbContext context)
    
        _context = context;
    

    // GET: Items
    public async Task<IActionResult> Index()
    
        var model = await _context.Item
                            .Where(a => a.ApplicationUser.Id == HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value)
                            .ToListAsync();
        return View(model);
    

数据库上下文:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>

    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    
    

    public DbSet<Item> Item  get; set; 

Startup.cs:

services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
        .AddEntityFrameworkStores<ApplicationDbContext>();

更新Pages/Shared/_LoginPartial.cshtml并将IdentityUser替换为ApplicationUser

@using Microsoft.AspNetCore.Identity
@inject SignInManager<ApplicationUser> SignInManager
@inject UserManager<ApplicationUser> UserManager

结果:

【讨论】:

我在哪里可以实际看到数据库中的应用程序用户,因为当我查看时,AspNetUsers 表中没有任何项目了。此外,当我在 items 表中创建一个项目时,它似乎有一个 null ApplicationUserId。 确保您已重新运行 add-migrationupdate-database。然后确保您已注册用户。此外,要在具有 ApplicationId 的项目中创建项目,您需要发布一个新线程。对于这个线程问题,已经解决了,你可以硬编码ApplicationId来测试我的数据。 好吧,我终于让它工作了。在控制器的创建方法中,我使用 var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); ApplicationUser applicationUser = await _userManager.GetUserAsync(User); item.ApplicationUser = applicationUser; 手动分配了当前用户

以上是关于如何仅在 ASP.NET MVC 中仅显示当前登录用户创建的项目的主要内容,如果未能解决你的问题,请参考以下文章