public async Task <ActionResult> AddComment(NewComment c) { if (c == null) { Response.StatusCode = (int)HttpStatusCode.BadRequest; return(Json(new { success = false, message = "Invalid parameter." })); } // Check for empty comment if (c.CommentContent.Replace(" ", "") == "<p><br></p>") { Response.StatusCode = (int)HttpStatusCode.BadRequest; return(Json(new { success = false, message = "Empty comment." })); } var userAppId = User.Identity.GetUserId(); if (userAppId == null) { Response.StatusCode = (int)HttpStatusCode.Unauthorized; return(Json(new { success = false, message = "Unable to verify logged in user" })); } using (var db = new ZapContext()) { var user = await db.Users .Include(usr => usr.Settings) .Where(u => u.AppId == userAppId) .FirstOrDefaultAsync() .ConfigureAwait(true); if (user == null) { if (Response != null) { Response.StatusCode = (int)HttpStatusCode.InternalServerError; } return(Json(new { success = false, message = "User not found in database" })); } var post = await db.Posts .Include(pst => pst.UserId) .Include(pst => pst.UserId.Settings) .FirstOrDefaultAsync(p => p.PostId == c.PostId) .ConfigureAwait(true); if (post == null) { if (Response != null) { Response.StatusCode = (int)HttpStatusCode.InternalServerError; } return(Json(new { success = false, message = "Post not found in DB." })); } Comment parent = null; if (c.IsReply) { parent = await db.Comments .Include(cmt => cmt.Post) .FirstOrDefaultAsync(cmt => cmt.CommentId == c.CommentId) .ConfigureAwait(true); } Comment comment = CreateComment(c, user, post, parent); var postOwner = post.UserId; if (postOwner.Settings == null) { postOwner.Settings = new UserSettings(); } // This is the owner of the comment being replied to User commentOwner = null; if (c.IsReply) { commentOwner = await db.Comments .Where(cmt => cmt.CommentId == c.CommentId) .Include(cmt => cmt.UserId.ProfileImage) .Select(cmt => cmt.UserId) .FirstOrDefaultAsync() .ConfigureAwait(true); if (commentOwner.Settings == null) { commentOwner.Settings = new UserSettings(); } } if (!c.IsReply) { post.Comments.Add(comment); } if (!c.IsTest) { db.Comments.Add(comment); await db.SaveChangesAsync().ConfigureAwait(true); } // Find user mentions try { // This could just move into the OnComment event and get processed in background? var doc = new HtmlDocument(); doc.LoadHtml(comment.Text); if (hasUserMention(doc)) { await eventService.OnUserMentionedInComment(comment.CommentId); } } catch (Exception e) { MailingService.SendErrorNotification( title: "User comment error", message: " Exception: " + e.Message + "\r\n Stack: " + e.StackTrace + "\r\n comment: " + c.CommentContent + "\r\n user: "******"_PartialCommentRenderVm", model: new PostCommentsViewModel() { PostId = c.PostId, StartVisible = true, CommentId = comment.CommentId, IsReply = comment.IsReply, IsDeleted = comment.IsDeleted, CommentVms = new List <PostCommentsViewModel>(), NestLevel = 0, ParentUserId = parent == null ? 0 : parent.UserId.Id, UserId = comment.UserId.Id, Score = comment.Score, ParentUserName = parent == null ? "" : parent.UserId.Name, ProfileImageVersion = comment.UserId.ProfileImage.Version, Text = comment.Text, TimeStamp = comment.TimeStamp, TimeStampEdited = comment.TimeStampEdited, UserAppId = comment.UserId.AppId, UserName = comment.UserId.Name, ViewerDownvoted = false, ViewerIgnoredUser = false, ParentCommentId = parent == null ? 0 : parent.CommentId, }); return(Json(new { HTMLString = CommentHTMLString, c.PostId, success = true, comment.IsReply, comment.CommentId, })); } }