9
votes

ASPNET CORE Ajax Post entraîne 400 demandes incorrectes

Je travaille sur ASP.NET Zero qui est basé sur ASP.NET Core. J'obtenais une erreur de demande incorrecte lorsque j'ai utilisé le contrôle de téléchargement KendoUI sur l'une de mes pages. Après de nombreuses recherches et investigations, j'ai réalisé que la requête HTTP POST Ajax échouait avec 400 erreurs de requête incorrectes. Mes exemples de code ci-dessous ont des lignes commentées pour d'autres scénarios que je teste. Aucun des messages existants dans stack over flow n'a résolu mon problème. I Ci-dessous mon appel ajax:

<div id="container">
    @Html.AntiForgeryToken()
    <div class="k-edit-field label">Vendor Name</div>
</div

Mon code Controller est: J'ai également essayé sans étendre MyTestProjectControllerBase et en utilisant simplement la classe de base Controller. Cela n'a pas fonctionné.

  $("#backBtn").on("click", function (e) {
        var t = $("input[name='__RequestVerificationToken']").val();
        $.ajax({
            url: "/test/TestCall",
            type: 'Post',
           /* data: JSON.stringify({ "Param1": "test" }),
            dataType:"json",
            processData: false,  */
            contentType: "application/json",  
            headers: {
                "RequestVerificationToken": t
            },
            success: function (result) {
                var res = result;
            },
            error: function (jqXHR) {
                var z = 3;
            },
            complete: function (jqXHR, status) {
                var x = 10;
            }
        });
    });

Que me manque-t-il? J'ai essayé d'utiliser le facteur et je vois ces informations supplémentaires "La requête ne peut pas être remplie en raison d'une mauvaise syntaxe"

n'a pas pu le comprendre après avoir passé 8 bonnes heures sur ce problème. Je ne sais pas si le problème concerne Asp.net core ou asp.net zero. Tous les pointeurs seraient grandement appréciés.

Mise à jour après vérification des commentaires de shyju: Le fichier Startup.cs contient le code suivant qui active AntiForgeryTokenAttribute

 services.AddMvc(options =>
        {
            options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
        }).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

Mises à jour de l'appel ajax et de la vue en fonction de la réponse de shyju:

public class TestController : MyTestProjectControllerBase
{
    public IActionResult Index()
    {
        return View();
    }

   [HttpPost]
    public ActionResult TestCall()
    {
        //return Content("Name is:" );
        return new ContentResult() { Content = "test" };
    }
}


4 commentaires

Avec le code que vous avez partagé, il ne devrait pas générer de réponse 400. Je viens de copier et coller votre code dans un projet local et il renvoie 200 OK pour moi. Il semble que vous ne partagiez pas du code qui est à l'origine de la réponse 400. Avez-vous un attribut ValidateAntiForgeryToken sur votre méthode d'action?


Non, ce projet a beaucoup de fichiers existants. mais le contrôleur que j'ai créé n'a rien de plus que ce que j'ai copié ici. ValidateAntiForgeryToken n'est pas sur ma méthode d'action. Avez-vous testé mon code sur aspnet core?


salut, je viens de chercher le ValidateAntiForgeryToken dans toute la solution. startup.cs a le code suivant services.AddMvc (options => {options.Filters.Add (new AutoValidateAntiforgeryTokenAttribute ());}). SetCompatibilityVersion (CompatibilityVersion.Version_2_1) ‌;


pouvez-vous l'ajouter à la question. Je vais poster une solution maintenant


3 Réponses :


9
votes

Il semble que le filtre AutoValidateAntiforgeryTokenAttribute soit appliqué globalement. Cela signifie que lorsqu'une méthode d'action HTTP Post est appelée (normale ou ajax), le framework vérifiera les données de la requête soumises et s'il ne trouve pas de jeton anti-falsification valide (en-tête RequestVerificationToken ), il sera considéré comme une mauvaise requête et une réponse 400 sera renvoyée.

Pour résoudre ce problème, vous pouvez lire explicitement la valeur de l'entrée masquée __RequestVerificationToken (générée par l'assistant de balise form) et l'envoyer vos en-têtes de requête ajax.

headers:
{
    "RequestVerificationToken": '@GetAntiXsrfRequestToken()'
},

Vous pouvez rendre le code plus robuste en injectant l'implémentation IAntiforgery dans la vue / page et en utilisant le GetAndStoreTokens .

Ajoutez ceci à votre vue

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
public string GetAntiXsrfRequestToken()
{
    return Xsrf.GetAndStoreTokens(Context).RequestToken;
}
}

et appelez cette fonction GetAntiXsrfRequestToken pour obtenir la valeur dans votre javascript (qui est à l'intérieur le fichier de vue)

var t = $("input[name='__RequestVerificationToken']").val();

$.ajax({
    url: "/test/TestCall",
    type: 'Post',
    headers:
    {
        "RequestVerificationToken": t
    },
    success: function (result) {
        alert("Success");
        var res = result;
    },
    error: function (jqXHR) {
        var z = 3;
    },
    complete: function (jqXHR, status) {
        var x = 10;
    }
});


7 commentaires

Merci pour l'aide. Cela n'a pas résolu le problème. cependant, si je commente le filtre global à tester, cela a permis à la demande de publication de passer. Vous avez correctement identifié le problème. mais la solution ne fonctionne pas pour une raison quelconque. je peux voir le jeton généré et passé à l'appel ajax. mettra à jour le nouvel appel ajax ajax dans la question


Envoie-t-il la valeur d'en-tête nécessaire? J'ai essayé votre code et a bien fonctionné pour moi.


Je me suis enregistré sous l'onglet Réseau dans Chrome; L'en-tête de demande a RequestVerificationToken défini sur le jeton. Y a-t-il autre chose que je devrais vérifier?


Avez-vous d'autres filtres côté serveur qui pourraient renvoyer une réponse 400?


pas certain. que dois-je rechercher? son code source zéro asp.net contient beaucoup de fichiers


Je ne vois aucun autre filtre dans startup.cs. continuera à chercher


Merci pour cette explication @Shyju. Cela m'a aidé à résoudre le même problème. Ce que je ne comprends pas, c'est le fait que mon appel ajax fonctionne depuis des semaines sans utiliser d'en-têtes pour spécifier le jeton. Soudainement aujourd'hui, j'ai eu une erreur http 400. Pourquoi donc? Je n'ai effectué aucune modification concernant le jeton ni dans le contrôleur, le modèle ou la vue.



0
votes

Essayez de spécifier l'en-tête avec X-XSRF-TOKEN .

Pour ABP Intercept XMLHttpRequest .

Puisque toutes les bibliothèques utilisent l'objet AJAX natif de JavaScript, XMLHttpRequest, vous pouvez définir un intercepteur simple pour ajouter le jeton à l'en-tête:

(function (send) {
    XMLHttpRequest.prototype.send = function (data) {
        this.setRequestHeader(abp.security.antiForgery.tokenHeaderName, abp.security.antiForgery.getToken());
        return send.call(this, data);
    };
})(XMLHttpRequest.prototype.send);

Pour abp.security.antiForgery.tokenHeaderName , sa valeur par défaut est X-XSRF-TOKEN p >


0 commentaires

0
votes

Dans Core - assurez-vous que votre balise

inclut method = "post" .

La méthode est nécessaire pour appeler l'assistant de balise de formulaire qui ajoute automatiquement le jeton anti-contrefaçon au formulaire. (J'ai accidentellement laissé tomber la méthode et je n'ai pas remarqué parce que je la postais en ajax.)


0 commentaires