I'm trying to make a forum web app using ASP.NET Core MVC and Identity. My ForumPost
model looks like this:
public class ForumPost
{
[Key]
public int PostId { get; set; }
[Required]
[MaxLength(32)]
public string PostName { get; set; }
[Required]
public string PostBody { get; set; }
[Required]
public IdentityUser User { get; set; }
}
I'm storing the IdentityUser
here so in the Posts table, it is replaced by a foreign key to the user Id
in the Users table, as explained here.
The Create
method in my controller looks like this:
public async Task<IActionResult> Create([Bind("PostId,PostName,PostBody")] ForumPost forumPost)
{
ModelState.Clear();
var user = await _userManager.GetUserAsync(User);
forumPost.User = user;
if (TryValidateModel(forumPost))
{
_context.Add(forumPost);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(forumPost);
}
But when I try to show the creator's Username
in the Index.cshtml
, it comes up blank. This is the shortened .cshtml
:
@model IEnumerable<ForumPost>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.PostName)
</td>
<td>
@Html.DisplayFor(modelItem => item.User.UserName)
</td>
</tr>
}
Am I doing something wrong here? What am I missing? Thanks!
In the original post, I assumed (and assumed wrong) that the User
field in the ForumPost
is filled in by automatically grabbing the IdentityUser
from the Users table using the foreign key assigned to the ForumPost
. It ended up not being the case, and I really don't need the entire user details, just the username.
Therefore, I've changed my ForumPost
code to this:
public class ForumPost
{
[Key]
public int PostId { get; set; }
[Required]
[MaxLength(32)]
public string PostName { get; set; }
[Required]
public string PostBody { get; set; }
[Required]
[ForeignKey("User")]
public string UserId { get; set; }
public IdentityUser User { get; set; }
}
I've added the UserId
there so that the following Index
action can have access to it. Doing this won't change the database, since the database already has a User Id foreign key pointing to the Users table. Here is the new Index
action:
public async Task<IActionResult> Index()
{
var posts = await _context.Posts.ToListAsync();
var postList = new List<PostIndexModel>();
foreach (var p in posts)
{
var userName = (from u in _context.Users
where u.Id.Equals(p.UserId)
select u.UserName).SingleOrDefault();
var post = new PostIndexModel()
{
PostId = p.PostId,
PostName = p.PostName,
UserName = userName
};
postList.Add(post);
}
return View(postList);
}
I've also created a new PostIndexModel
view model that only shows a few things:
public class PostIndexModel
{
public int PostId { get; set; }
[Display(Name = "Post Name")]
public string PostName { get; set; }
[Display(Name = "Post Creator")]
public string UserName { get; set; }
}