2017-08-24 2 views
0

J'ai le code jQuery suivant qui envoie des données avec JSON.stringify à la classe de contrôleur ASP.NET MVC. Tout fonctionne bien sans l'introduction de l'AntiForgeryToken. Maintenant, lorsque je commence à implémenter AntiForgeryToken dans la base de code, cela ne fonctionne pas et génère une erreur: Le champ de formulaire anti-falsification requis "__RequestVerificationToken" n'est pas présent.Passage de AntiForgeryToken dans une requête de publication JSON avec JSON.stringify ne fonctionne pas

HTML

<form action="javascript: void(0)" id="frmMain"> 
    @Html.AntiForgeryToken() 
    .... 
</form> 

code jQuery:

function saveDetails() {    
    var testViewModel = {}; 
    testViewModel.ArticleType = $("#SubType").val() 
    testViewModel.PublishedDate = $("#publishDate").val(); 
    var token = $('#frmMain input[name=__RequestVerificationToken]').val(); 

    var languages = []; 
    $.each($('#language').val(), function (index, value) { 
     var languageContent = {}; 
     languageContent.Language = value; 
     languageContent.Author = $("#author-" + value).val(); 
     languageContent.TeaserText = $("#teaser-" + value).val(); 
     languageContent.body = $("#content-" + value).val(); 
     languageContent.Title = $("#title-" + value).val(); 
     languages.push(languageContent); 
    }); 
    testViewModel.LanguageContent = languages; 
    testViewModel.Author = testViewModel.LanguageContent[0].Author; 
    testViewModel.ArticleId = aId; 

    $.ajax({ 
     type: "POST", 
     url: "@Url.Action("SaveDetails", "Test")", 
     data: JSON.stringify({ articleViewModel: articleViewModel, __RequestVerificationToken: token }), 
     contentType: "application/json; charset=utf-8", 
     dataType: "json", 
     cache: false, 
     success: function (data) { 
      var url = "@Url.Action("SiteDetails", "Test")"; 
      window.location.href = url + "?ArticleId=" + aId; 
     } 
    }); 
} 

TestController.cs

[HttpPost] 
[ValidateAntiForgeryToken] 
public JsonResult SaveDetails([Bind(Include = "ArticleId,PublishedDate,Author,ArticleType,LanguageContent")]TestObject testViewModel) 
{ 
    if (!ModelState.IsValid) 
    { 
     return Json(new { success = false }); 
    } 
} 

Quelqu'un peut-il me aider par fournir leurs conseils pour résoudre ce problème

+0

supprimer json et stringify et il suffit de publier les données telles quelles – Nkosi

+0

Voir [cette réponse] (https://stackoverflow.com/questions/45773645/the-required-anti-forgery-form-field-requestverificationtoken-is-not -present/45777177 # 45777177). Mais le fait que votre formulaire génère des contrôles pour une collection avec ces attributs "id" suggère que vous faites tout faux. –

+0

Et le fait que vous utilisez ajax pour soumettre un pour et ensuite rediriger est inutile. Générez juste votre vue correctement (référez-vous [cette réponse] (http://stackoverflow.com/questions/30094047/html-table-to-ado-net-datatable/30094943#30094943) pour générer des contrôles de formulaire pour une collection, ou [ celui-ci] (http://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308) si vous ajoutez dynamiquement des contrôles) et faites une soumission normale et rediriger dans la méthode POST –

Répondre

1

J'ai ajouté un autre filtre:

namespace TestDetails.Controllers 
{ 
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)] 
    public sealed class ValidateHeaderAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter 
    { 
     public void OnAuthorization(AuthorizationContext filterContext) 
     { 
      if (filterContext == null) 
      { 
       throw new ArgumentNullException("filterContext"); 
      } 

      var httpContext = filterContext.HttpContext; 
      var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName]; 
      AntiForgery.Validate(cookie != null ? cookie.Value : null, httpContext.Request.Headers["__RequestVerificationToken"]); 
     } 
    } 
} 

TestController.cs

[HttpPost] 
[ValidateHeaderAntiForgeryToken] 
public JsonResult SaveDetails([Bind(Include = "ArticleId,PublishedDate,Author,ArticleType,LanguageContent")]TestObject testViewModel) 
{ 
    if (!ModelState.IsValid) 
    { 
     return Json(new { success = false }); 
    } 
} 

function saveDetails() {    
    var testViewModel = {}; 
    testViewModel.ArticleType = $("#SubType").val() 
    testViewModel.PublishedDate = $("#publishDate").val(); 
    var token = $('#frmMain input[name=__RequestVerificationToken]').val(); 

    var languages = []; 
    $.each($('#language').val(), function (index, value) { 
     var languageContent = {}; 
     languageContent.Language = value; 
     languageContent.Author = $("#author-" + value).val(); 
     languageContent.TeaserText = $("#teaser-" + value).val(); 
     languageContent.body = $("#content-" + value).val(); 
     languageContent.Title = $("#title-" + value).val(); 
     languages.push(languageContent); 
    }); 
    testViewModel.LanguageContent = languages; 
    testViewModel.Author = testViewModel.LanguageContent[0].Author; 
    testViewModel.ArticleId = aId; 


    $.ajax({ 
     type: "POST", 
     url: "@Url.Action("SaveDetails", "Test")",   
     headers: { 
       "__RequestVerificationToken": token 
     }, 
     data: JSON.stringify(testViewModel), 
     cache: false, 
     success: function (data) { 
      var url = "@Url.Action("SiteDetails", "Test")"; 
      window.location.href = url + "?ArticleId=" + aId; 
     } 
    }); 
} 

Il fonctionne très bien maintenant.