c# - ASP.NET Core MVC Identity - 如何查看当前登录的用户?
问题描述
这是我的 UserIndex.cshtml 视图,其中列出了属于当前登录用户的所有帖子。
@model IEnumerable<AProject.Areas.Identity.Data.Post>
@using Microsoft.AspNetCore.Identity
@using AProject.Areas.Identity.Data
@inject SignInManager<ApplicationUser> SignInManager
@inject UserManager<ApplicationUser> UserManager
@{
ViewData["Title"] = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h3> My posts </h3>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Title)
</th>
<th>
@Html.DisplayNameFor(model => model.DateCreated)
</th>
<th>
@Html.DisplayNameFor(model => model.Category)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
@if( @UserManager.GetUserName(User) == item.User.UserName )
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Title)
</td>
<td>
@Html.DisplayFor(modelItem => item.DateCreated)
</td>
<td>
@Html.DisplayFor(modelItem => item.Category.Name)
</td>
<td>
<td>
<a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
<a asp-action="Details" asp-route-id="@item.Id">Details</a> |
<a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
</td>
</tr>
}
}
</tbody>
</table>
显然,在以下行中存在错误@if( @UserManager.GetUserName(User) == item.User.UserName )
:NullReferenceException:对象引用未设置为对象的实例。我不知道为什么会出现此错误,因为一切都工作了一段时间(它在表中仅列出登录用户的帖子)然后我正在处理另一个视图,当我返回此页面时出现错误。我什至试过这个@if( @User.Identity.Name == item.User.UserName )
,但仍然有错误。我什至撤消了我在错误之前所做的所有更改,但它仍然不起作用。如果有帮助,这也是我的控制器:
[Authorize]
public class PostsController : Controller
{
private readonly AProjectContext _context;
private readonly UserManager<ApplicationUser> _userManager;
public PostsController(AProjectContext context, UserManager<ApplicationUser> userManager)
{
_context = context;
_userManager = userManager;
}
// GET: Posts
public async Task<IActionResult> Index()
{
var aprojectContext = _context.Posts.Include(p => p.Category).Include(p => p.User);
return View(await aprojectContext.ToListAsync());
}
public async Task<IActionResult> UserIndex()
{
var aprojectContext = _context.Posts.Include(p => p.Category).Include(p => p.User);
return View(await aprojectContext.ToListAsync());
}
// GET: Posts/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var post = await _context.Posts
.Include(p => p.Category)
.Include(p => p.User)
.FirstOrDefaultAsync(m => m.Id == id);
if (post == null)
{
return NotFound();
}
return View(post);
}
// GET: Posts/Create
public IActionResult Create()
{
ViewData["CategoryId"] = new SelectList(_context.Set<Category>(), "Id", "Name");
return View();
}
// POST: Posts/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Title,Summary,Content,CategoryId")] Post post)
{
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);
var userName = User.FindFirstValue(ClaimTypes.Name);
ApplicationUser appUser = await _userManager.GetUserAsync(User);
string userEmail = appUser?.Email;
post.DateCreated = DateTime.Now;
post.User = appUser;
post.UserId = userId;
if (ModelState.IsValid)
{
_context.Add(post);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["CategoryId"] = new SelectList(_context.Set<Category>(), "Id", "Name", post.Category.Name);
return View(post);
}
// GET: Posts/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var post = await _context.Posts
.Include(p => p.Category)
.Include(p => p.User)
.FirstOrDefaultAsync(m => m.Id == id);
if (post == null)
{
return NotFound();
}
ViewData["CategoryId"] = new SelectList(_context.Set<Category>(), "Id", "Name", post.Category.Name);
return View(post);
}
// POST: Posts/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,Summary,Content,CategoryId")] Post post)
{
if (id != post.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(post);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!PostExists(post.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
ViewData["CategoryId"] = new SelectList(_context.Set<Category>(), "Id", "Name", post.Category.Name);
return View(post);
}
// GET: Posts/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var post = await _context.Posts
.Include(p => p.Category)
.Include(p => p.User)
.FirstOrDefaultAsync(m => m.Id == id);
if (post == null)
{
return NotFound();
}
return View(post);
}
// POST: Posts/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var post = await _context.Posts.FindAsync(id);
_context.Posts.Remove(post);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
private bool PostExists(int id)
{
return _context.Posts.Any(e => e.Id == id);
}
有没有办法通过控制器中当前登录的用户过滤帖子,然后将这些帖子发送到视图,而不是过滤视图中的所有帖子,如果这仍然不起作用?
**** 更新 ****
事实证明问题不是@UserManager.GetUserName(User)
因为item.User.UserName
Post 项目没有用户。现在可以了。另外,如果有人有类似的问题,我发现最好在控制器中过滤帖子,现在看起来像这样
public async Task<IActionResult> UserIndex()
{
var userName = User.FindFirstValue(ClaimTypes.Name); // will give the user's userName
var aprojectContext = _context.Posts.Include(p => p.Category).Include(p => p.User).Where(p => p.User.UserName == userName);
return View(await aprojectContext.ToListAsync());
}
感谢大家的建议和帮助。
解决方案
试试这个来获取 userId :
string userId = User.Claims.First(c => c.Type == "UserID").Value;
对于获取用户帖子,您应该在表/视图中添加一列,该列正在处理每个帖子的 userId,然后您可以根据需要过滤表/视图。
推荐阅读
- magento - Jmeter:由于表单密钥问题,无法登录 Magento
- api - 在语义学者 api 中搜索引用的文本
- java - 将已检查异常的*原因*重新抛出为未检查异常有什么缺点吗?
- java - 使用 Vaadin UI 进行改造
- c++ - 二进制“<<”:未找到采用“c1”类型的右侧操作数的运算符
- javascript - 从Javascript中的字符串中删除除数值之外的所有值
- node.js - 在 cPanel 主机上运行的节点应用程序在闲置 30 分钟后关闭
- python - Terraform 抱怨 lambda 中使用了列表
- python - 烧瓶在 send_file() 后无法删除文件
- firebase - 关于firestore更改的本地通知