First Last

First Last

  • 983
  • 648
  • 66.5k

anti-forgery form field"__RequestVerificationToken" is not present

Aug 13 2020 4:03 PM
I have a view that is NOT a form. I am doing an Ajax POST with jQuery to the server without having any form at all. It displays a blog and also it accepts a blog comment. I want to take that blog comment and save it to the database.
 
I have a @Html.AntiForgeryToken() right before the text field (the blog comment) that I want to use to save to the database.
 
I have the  [ValidateAntiForgeryToken] attribute before the controller aciton method. 
 
I pass append the token to the data to be sent to the method:
data: AddAntiForgeryToken({ blogComment, userProfileProcessType }), 
 
I'm getting: The required anti-forgery form field"__RequestVerificationToken" is not present in asp.net mvc
 
Here is the view: 
  1. <h2 class="page-header"><span class="blogtitle">@Session["BlogTitle"]</span></h2>    
  2.     @{    
  3.         Layout = "~/Views/Shared/_LayoutUser.cshtml";    
  4.     }    
  5.     @if (ViewBag.errormessage != null)    
  6.     {    
  7.         <p class="alert alert-danger" id="errorMessage">@ViewBag.errormessage</p>    
  8.     }   
  9.     <br />   
  10.     <div>    
  11.         <a href="@Url.Action("LoadDropdownBlogCategorysInBlogsPublished", "BlogPublished")">Return To Select a Blog</a>    
  12.     </div>    
  13.     <br />   
  14.     @if (Model != null)    
  15.     {    
  16.     <div class="panel panel-default toppanel">    
  17.         <div class="panel-body">    
  18.             <div class="row">    
  19.                 <div class="col-md-2">    
  20.                     @Html.LabelFor(model => model.BlogPublishedByBlogId.CreatedDateTime)    
  21.                     @Html.TextBoxFor(model => model.BlogPublishedByBlogId.CreatedDateTime, new { @class = "form-control", @disabled = "disabled" })    
  22.                 </div>    
  23.                 <div class="col-md-2">    
  24.                     @Html.LabelFor(model => model.BlogPublishedByBlogId.ModifiedDateTime)    
  25.                     @Html.TextBoxFor(model => model.BlogPublishedByBlogId.ModifiedDateTime, new { @class = "form-control", @disabled = "disabled" })    
  26.                 </div>    
  27.             </div>    
  28.             <br />    
  29.             <div class="row">    
  30.                 <div>    
  31.                     @Html.DisplayFor(model => model.BlogPublishedByBlogId.BlogContent, new { @class = "form-control blogContent", @disabled = "disabled" })    
  32.                 </div>    
  33.             </div>    
  34.             <br />    
  35.             <br />   
  36.             <div class="panel-footer">    
  37.                 <button type="button" class="btn btn-primary Comment" data-id="@Model.BlogPublishedByBlogId.BlogId" value="Comment">    
  38.                     <span class="glyphicon glyphicon-comment" aria-hidden="true"></span> Get Comment(s)    
  39.                 </button>    
  40.             </div>    
  41.             <div id="@string.Format("{0}_{1}","commentsBlock", @Model.BlogPublishedByBlogId.BlogId)" style="border: 1px solid #f1eaea; background-color: #eaf2ff;">    
  42.                 <div class="AddCommentArea" style="margin-left: 30%;  margin-bottom: 5px; margin-top: 8px;">    
  43.                     @Html.AntiForgeryToken()    
  44.                     <input type="text" id="@string.Format("{0}_{1}", "comment", @Model.BlogPublishedByBlogId.BlogId)" class="form-control" placeholder="Add a comment..." style="display: inline;" />    
  45.                     <button type="button" class="btn btn-primary addComment" data-id="@Model.BlogPublishedByBlogId.BlogId"><span class="glyphicon glyphicon-comment" aria-hidden="true"></span></button>    
  46.                 </div>    
  47.             </div>    
  48.         </div>    
  49.     </div>    
  50.     }    
  51.     
  52.     @Scripts.Render("~/bundles/jqueryval")    
  53.     @Scripts.Render("~/bundles/jquery")    
  54.     @Scripts.Render("~/bundles/bootstrap")    
  55.     @Styles.Render("~/Content/css")    
  56.     
  57.     @section Scripts    
  58.     {    
  59.     <script type="text/javascript">    
  60.         $(document).ready(function () {    
  61.             $('.Comment').on('click'function () {    
  62.                 var blogId = $(this).attr("data-id");    
  63.                 var allCommentsArea = $('<div>').addClass('allComments_' + blogId);    
  64.     
  65.                 $.ajax({    
  66.                     type: 'GET',    
  67.                     url: '@Url.Action("GetBlogComments", "BlogPublished")',    
  68.                     data: { blogId: blogId },    
  69.                     success: function (response) {    
  70.                         if ($('div').hasClass('allComments_' + blogId + ''))    
  71.                         {    
  72.                             $('div[class=allComments_' + blogId + ']').remove();    
  73.                         }    
  74.     
  75.                         // Dynamically building the HTML to hold the comments (the list) returned.    
  76.                         // The area for the BlogPublished/_Comments.cshtml to be placed.    
  77.                         allCommentsArea.html(response);    
  78.                         allCommentsArea.prependTo('#commentsBlock_' + blogId);    
  79.                     },    
  80.                     error: function (xhr, ajaxOptions, thrownError) {    
  81.                         alert("Critical Error: something is wrong in the call to GetBlogComments! Status: " + xhr.status + ". Error: " + thrownError.toString() + ". Response Text: " + xhr.responseText);    
  82.                     }    
  83.                 })    
  84.             });    
  85.     
  86.             // For when clicking the 'addComment' button.    
  87.             $('.addComment').on('click'function () {    
  88.                 var blogId = $(this).attr('data-id');    
  89.                 var blogCommentContent = $('#comment_' + blogId).val();    
  90.                 var dateTimeNow = new Date();    
  91.                 var userProfileProcessType = "I";    
  92.     
  93.                 // An object - the BlogComment model to be passed to the controller method.    
  94.                 var blogComment = {    
  95.                     BlogId: blogId,    
  96.                     BlogCommentContent: blogCommentContent,    
  97.                     DateTimeOfBlogComment: dateTimeNow.toLocaleString()    
  98.                 };    
  99.       
  100.                 $.ajax({    
  101.                     type: 'POST',    
  102.                     url: '@Url.Action("ProcessSaveBlogComment", "BlogPublished")',    
  103.                     data: AddAntiForgeryToken({ blogComment, userProfileProcessType }),    
  104.                     success: function (response) {    
  105.                         $('div[class=allComments_' + blogId + ']').remove();   
  106.                         // Dynamically building the HTML to hold the comments (the list) returned which now includes the added comment.    
  107.                         var allCommentsArea = $('<div>').addClass('allComments_' + blogId);    
  108.                         allCommentsArea.html(response);    
  109.                         allCommentsArea.prependTo('#commentsBlock_' + blogId);  
  110.                         $("#comment_" + blogId).val('')    
  111.                     },    
  112.                     error: function (xhr, ajaxOptions, thrownError) {    
  113.                         alert("Critical Error: something is wrong in the call to ProcessSaveBlogComment! Status: " + xhr.status + ". Error: " + thrownError.toString() + ". Response Text: " + xhr.responseText);    
  114.                     }    
  115.                 });    
  116.             });   
  117.             jQuery(".timeago").timeago();    
  118.         });   
  119.         AddAntiForgeryToken = function (data) {    
  120.             data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val();    
  121.             return data;    
  122.         };    
  123.     </script>    
  124.     }   
 
Here is the controller:
  1. [HttpPost][ValidateAntiForgeryToken]  
  2. public async Task ProcessSaveBlogComment(BlogComment blogComment, string userProfileProcessType) {  
  3.   if (ModelState.IsValid) {  
  4.     blogComment.UserId = Convert.ToInt32(Session["UserId"]);  
  5.     BLL_BlogPublished bll_BlogPublished = new BLL_BlogPublished();  
  6.     ProcessSaveBlogCommentResults processSaveBlogCommentResults = new ProcessSaveBlogCommentResults();  
  7.   
  8.     try {  
  9.       processSaveBlogCommentResults = await bll_BlogPublished.ProcessSaveBlogComment(blogComment, Session["UserName"].ToString(), userProfileProcessType);  
  10.   
  11.       if (processSaveBlogCommentResults.ApiErrorMessage == null) {  
  12.         if (processSaveBlogCommentResults.Status == 2) {  
  13.           ViewBag.errormessage = "Process Violation: You are not the 'blog comment' creator so you cannot update the blog comment.";  
  14.         }  
  15.         else if (processSaveBlogCommentResults.Status == 3) {  
  16.           ViewBag.errormessage = "Process Violation: Not the correct 'blog id' so cannot update the blog comment.";  
  17.         }  
  18.       }  
  19.       else {  
  20.         ViewBag.errormessage = processSaveBlogCommentResults.ApiErrorMessage;  
  21.       }  
  22.     }  
  23.     catch(Exception ex1) {  
  24.       exceptionMessage = "Server error on saving the blog comment. Please contact the administrator.";  
  25.   
  26.       try {  
  27.         ClientErrorResult clientErrorResult = new ClientErrorResult();  
  28.   
  29.         clientErrorResult = await ProcessClientError(Session["UserName"].ToString(), ex1.Message, "Server error on saving the blog comment. User name: " + Session["UserName"] + ". Post method: ProcessSaveBlogComment.");  
  30.   
  31.         if (clientErrorResult.ApiErrorMessage == null) {  
  32.           ViewBag.errormessage = exceptionMessage;  
  33.         }  
  34.         else {  
  35.           ViewBag.errormessage = clientErrorResult.ApiErrorMessage;  
  36.         }  
  37.       }  
  38.       catch(Exception ex2) {  
  39.         ViewBag.errormessage = "Failure in ProcessClientError. Exception error: " + ex2.Message + ". Original error: " + exceptionMessage;  
  40.       }  
  41.     }  
  42.   }  
  43.   
  44.   return RedirectToAction("GetBlogComments""BlogPublished"new {  
  45.     blogId = blogComment.BlogId  
  46.   });  
  47. }   
Before leaving the AddAntiForgeryToken function - the console log.
 
 
 
The network tab - cookies.
 
 
 
Part 1 of the Network tab - header (has the request verification token in the cookie).
 
 
Part 2 of the Network tab - header (has my data to send to the controller).
 
 
Error:
8/13/2020 4:49:56 PM
------------------------------------------------------------------------------------------------
Controller Name :- BlogPublished
Action Method Name :- ProcessSaveBlogComment
------------------------------------------------------------------------------------------------
System.Web.Mvc.ExceptionContext
Message ---
{0}The required anti-forgery form field "__RequestVerificationToken" is not present.
.Net Error ---
{0}Check MVC Ajax Code For Error
Source ---
{0}System.Web.WebPages
StackTrace ---
{0} at System.Web.Helpers.AntiXsrf.TokenValidator.ValidateTokens(HttpContextBase httpContext, IIdentity identity, AntiForgeryToken sessionToken, AntiForgeryToken fieldToken)
at System.Web.Helpers.AntiXsrf.AntiForgeryWorker.Validate(HttpContextBase httpContext)
at System.Web.Helpers.AntiForgery.Validate()
at System.Web.Mvc.ValidateAntiForgeryTokenAttribute.OnAuthorization(AuthorizationContext filterContext)
at System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor)
at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass3_1.b__0(AsyncCallback asyncCallback, Object asyncState)
TargetSite ---
{0}Void ValidateTokens(System.Web.HttpContextBase, System.Security.Principal.IIdentity, System.Web.Helpers.AntiXsrf.AntiForgeryToken, System.Web.Helpers.AntiXsrf.AntiForgeryToken)

Answers (1)