thankyoukindly thankyoukindly - 4 months ago 12
C# Question

ApplicationUser is null when returning PartialView

I have a comment class that when created stores the id of the user, and from my understanding the entity framework maps this Id to the user. This works when initially loading the view. But when I add a new comment, and return the PartialView for some reason the Author (application user) is null and an exception is thrown. However, if I reload the page the new comment is shown with the correct ApplicationUser information displayed.

public class Comment
{
public Guid ID { get; set; }
public string Text { get; set; }


[Required]
public string AuthorId { get; set; }

[ForeignKey("AuthorId")]
public virtual ApplicationUser Author { get; set; }

public DateTime DateSubmitted { get; set; }
public Guid PostID { get; set; }
public virtual Post Post { get; set; }

}


I use a ViewModel to handle the data on the view.

public class CommentViewModel
{
public string Text { get; set; }
public Guid PostID { get; set; }
public List<Comment> CommentList { get; set; }
}


Here is my controller Action.

public ActionResult CreateComment(CommentViewModel viewModel)
{
if (ModelState.IsValid)
{
var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
var currentUser = manager.FindById(User.Identity.GetUserId());

var comment = new Comment
{
ID = Guid.NewGuid(),
AuthorId = currentUser.Id,
DateSubmitted = DateTime.Now,
PostID = viewModel.PostID,
Text = viewModel.Text

};

Debug.Write("PostID:" + comment.PostID + "Author: " + "Text: " + comment.Text);
db.Comments.Add(comment);
db.SaveChanges();
CommentViewModel model = new CommentViewModel();
model.CommentList = db.Comments.Where(i => i.PostID == comment.PostID).OrderByDescending(c => c.DateSubmitted).ToList();
return PartialView(model);

}
else
{
Debug.Write("not valid");

}

return PartialView(viewModel);

}


This foreach displays all comments from the CommentList. When submitting a new comment, it crashes on the line that should be displaying @item.Author.Id.

foreach (var item in Model.CommentList)
{


<div class="row">
<div class="col-sm-1">
<div class="thumbnail">
<img class="img-responsive user-photo" src="https://ssl.gstatic.com/accounts/ui/avatar_2x.png">
</div><!-- /thumbnail -->
</div><!-- /col-sm-1 -->

<div class="col-sm-5">
<div class="panel panel-default">
<div class="panel-heading">
<strong>@item.Author.Id</strong>

<time class="timeago" datetime="@item.DateSubmitted"></time>

</div>
<div class="panel-body">
@item.Text
</div><!-- /panel-body -->
</div><!-- /panel panel-default -->
</div><!-- /col-sm-5 -->
</div>

}

Answer

Comment.Author is virtual so you need to explicitly load it after saving. Change:

model.CommentList = db.Comments.Where(i => i.PostID == comment.PostID).OrderByDescending(c => c.DateSubmitted).ToList();

To:

model.CommentList = db.Comments
    .Include(c => c.Author)
    .Where(i => i.PostID == comment.PostID)
    .OrderByDescending(c => c.DateSubmitted).ToList();

See https://msdn.microsoft.com/en-us/library/gg671236%28v=vs.103%29.aspx#Anchor_1

Comments