如何仅在 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 中仅显示当前登录用户创建的项目的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP .NET MVC 中仅验证模型的一部分?

如何在 ASP.NET MVC 中获取当前用户

ASP.NET MVC Web API 身份验证令牌安全问题

Asp.Net Mvc 突出显示当前页面链接技术?

我如何根据 mvc asp.net 中的登录用户切换视图

如何在 ASP.Net MVC 中将登录视图实现为 jQueryUI 对话框