2013-07-25 8 views
17

Ho cercato esempi su come farlo in SO e per quanto posso dire ho provato tutti gli esempi che riesco a trovare senza successo fino ad ora. Ho provato a modificare alcune delle implementazioni nel mio scenario, ma questo ha finora fallito.AJAX Posting ValidateAntiForgeryToken senza modulo per MVC Metodo di azione

ho questo sulla mia pagina in _layout.cshtml così ho sempre un gettone disponibili:

<form id="__AjaxAntiForgeryForm" action="#" method="post"> @Html.AntiForgeryToken()</form> 

Ho anche questo metodo nel mio JavaScript utils del file:

AddAntiForgeryToken = function (data) { 
    data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val(); 
    return data; 
}; 

Questo è tutto funziona come previsto e ottengo un token anti-contraffazione. Il mio codice distacco attuale è:

myPage.saveData = function() { 
    var saveUrl = '/exercises/PostData'; 

    var myData = JSON.stringify(myPage.contextsArrays); 

    $.ajax({ 
     type: 'POST', 
     async: false, 
     url: saveUrl, 
     data: AddAntiForgeryToken({ myResults: myData }), 
     success: function() { 
      alert('saved'); 
     }, 
     dataType: 'json', 
     contentType: "application/json; charset=utf-8" 
    }); 
}; 

Il mio metodo di azione simile a questa:

[HttpPost, ValidateAntiForgeryToken, JsonExceptionFilter] 
    public JsonResult PostData(List<ResultsDc> myResults) 
    { 
     return Json(_apiClient.SubmitResults(myResults)); 
    } 

Ho testato questo con le varie implementazioni ho cercato e la risposta è sempre:

Non sto postando un modulo è solo una matrice di dati ma controllando i dati effettivamente pubblicati, il Json non sembra corretto (è tutto codificato) ma il nome del parametro __RequestVerificationToken è il e anche il valore del token è presente.

Sono abbastanza confuso da tutto questo al momento e non riesco a trovare il modo corretto di inviare il token in modo che venga richiamata la mia azione MVC. Se io rimuovere l'attributo ValidateAntiForgeryToken e hanno JSON.stringify(myPage.contextsArrays); come i dati JSON sembra corretto (in chiaro) e si associa bene.

Come faccio ad avere questo token inviato correttamente senza un modulo?

+0

Sono confuso. Se non hai visto questo e la tua risposta qui sotto è qualcun altro (ho visto quel codice su altre risposte su SO) perché stai cercando di rispondere a qualcosa che non capisci ?? – Jammer

+0

Non è necessario separare gli attributi ... – Jammer

risposta

27

colpisce cartone sviluppatore nuovo.

Tutto quello che dovevo fare era rimuovere:

contentType: "application/json; charset=utf-8" 

E così facendo (che cambia il tipo di richiesta POST stato fatto), per ottenere il contenuto JSON della proprietà data effettiva di legarsi in modo corretto al tuo T modello di tipo NonJSON.stringify() i dati.

+0

Life saver ... grazie! questo commento era tutto ciò di cui avevo bisogno dopo 2 giorni di ricerca. Molto obbligato. –

+0

Superbo! - Ho seguito un sacco di soluzioni, ma senza successo, questo tuttavia si è rivelato il colpevole, molte grazie! – Dal

+0

Grazie! Sprecate ore su questo !!! Leggi l'articolo dopo l'articolo e non andava da nessuna parte. Ho provato così tante cose diverse ma quasi tutte fornendo lo stesso risultato finale che includeva il token di verifica durante la pubblicazione e non riuscivo a farlo funzionare finché non ho trovato il tuo suggerimento per caso! Ancora non ci posso credere! Grazie per aver condiviso!! – Thierry

1

La validazione è codificato a guardare i dati del modulo.

https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.WebPages/Helpers/AntiXsrf/AntiForgeryTokenStore.cs

public AntiForgeryToken GetFormToken(HttpContextBase httpContext) 
    { 
     string value = httpContext.Request.Form[_config.FormFieldName]; 

si può simulare un invio di form seguendo un certo formato. Per questo, vedere How to mimic an HTML form submission in a POST request?

Se si desidera, si può anche fare il proprio validatore. How to POST JSON data to an Asp.Net MVC 2 app with ValidateAntiForgeryToken spiega come farlo. È per MVC 2, ma puoi raccogliere alcune idee da esso.

+0

Non appena ho postato questo ho risolto tutto. – Jammer

+0

La maggior parte di questo è completa overkill e totalmente non necessaria ... – Jammer

+0

Certo, il validatore personalizzato potrebbe essere visto come eccessivo. Spiego solo la causa del problema e due possibili soluzioni. La risposta che hai postato è praticamente il risultato finale delle informazioni nel mio primo link. – Stijn

9

(NOTA: So che questo non è tutto ciò che molto diverso da quello che è già qui)

Mi rendo conto che questo è già stato risposto, ma ho fatto questo piuttosto un po 'e aggiungo la mia risposta a la pila.Non ho moduli nel mio sito, quindi ho dovuto trovare dei modi per gestirli. Un sacco di ricerche su StackOverflow e alcuni blog mi hanno finalmente fornito le informazioni di cui avevo bisogno.

In primo luogo, ecco il mio codice nella parte superiore della mia pagina "master" (MVC Razor):

@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" })) 
{ 
    @Html.AntiForgeryToken() 
} 

Poi, in tutte le chiamate Ajax (jQuery), comincio così:

var token = $("#__AjaxAntiForgeryForm input").val(); 
var dataObject = { 
    __RequestVerificationToken: token, 
    myData: "whatever" 
}; 

$.ajax({ 
    url: '@Url.Action("action", "controller")', 
    type: 'POST', 
    dataType: 'json', 
    data: dataObject, 
    error: function (jqXHR, textStatus, errorThrown) { 
    console.log("ERROR!"); 
    }, 
    success: function (data) { 
    //whatever 
    } 
}); 

Infine, nel lato controller di cose, questo funziona bene:

public class controllerController : Controller 
{ 
    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public JsonResult action (myModel myData) 
    { 
     return Json(new { Success = "true" }, JsonRequestBehavior.DenyGet); 
    } 
} 

Speriamo che questo avrebbe aiutato gli altri nella stessa barca.

Problemi correlati