j'ai dû mettre en œuvre ce type de fonctionnalité et moi-même récemment trouvé cette question et le lien vers le blog de Jesse Taber très utile, donc je pensais que je voudrais partager ma mise en œuvre ici en utilisant ASP.NET MVC.
La théorie de base est que vous transmettez un jeton au contrôleur lorsque vous soumettez le formulaire, et le contrôleur définit un cookie avec cette valeur dans la réponse lorsque le téléchargement se produit.
(Toutes mes excuses pour le VB.NET)
Ajouter une propriété à votre modèle pour stocker le jeton:
Public Property DownloadToken As String
Réglez ensuite le cookie dans la réponse avant de retourner le résultat:
If Response.Cookies("MyFileDownloadToken") Is Nothing Then
Dim cookie As New HttpCookie("MyFileDownloadToken", ParameterModel.DownloadToken)
Response.Cookies.Add(cookie)
Else
Response.Cookies("MyFileDownloadToken").Value = ParameterModel.DownloadToken
End If
Ajoutez la propriété jeton comme un champ caché sur votre formulaire:
@Html.HiddenFor(Function(m) m.DownloadToken)
Ensuite, nous pouvons utiliser JavaScript pour contrôler le bouton sumbit et le plugin jQuery Cookie pour obtenir et définir la valeur des cookies.
var fileDownloadChecker;
$(function()
{
$("#MyForm").submit(function()
{
$(".validation-summary-errors").empty(); //Clear any validation errors from a previous failed form submission
PreventResubmission();
});
$("#submitButton").prop("disabled", false);
}
function PreventResubmission()
{
//Use the current time as a unique token that we can check for in the response
var token = new Date().getTime();
//Set the token so that it is passed through to the controller
$("#DownloadToken").val(token);
//Prevent the user from resubmitting the form
$("#submitButton").prop("disabled", true);
$("#submitButton").val("Running...");
//Check once a second for the token in the response
fileDownloadChecker = window.setInterval(function()
{
var cookieValue = $.cookie("MyFileDownloadToken");
if (cookieValue == token)
{
EnableFormSubmission();
}
}, 1000);
}
function EnableFormSubmission()
{
//Stop checking for the token
window.clearInterval(fileDownloadChecker);
fileDownloadChecker = 0;
//Clear the hidden field
$("#DownloadToken").val("");
//Clear the cookie that contains the token
$.cookie("MyFileDownloadToken", null, { path: "/" });
//Enable the form submit button
$("#submitButton").prop("disabled", false);
$("#submitButton").val("Run");
}
choses à noter:
1) Les paramètres de chemin par défaut pour la classe HttpCookie et l'interface Cookie jQuery sont différents. Par défaut, le HttpCookie est créé à la racine ('/'), tandis que le plugin jQuery va rechercher (et définir) les cookies en fonction du chemin actuel. Si vous lisez un cookie, il se replie et regarde les autres chemins. Nous spécifions donc le chemin au moins lors de l'effacement du cookie. (Entré dans une situation où le code fonctionnerait une fois mais échouerait par la suite car il trouverait le cookie dans le chemin actuel et retournerait toujours cette valeur)
2) J'ai ajouté une ligne pour activer le bouton soumettre quand la page charges, car si la page était rafraîchie pour une raison quelconque durant la phase d'exécution, elle conserverait l'état "désactivé" du bouton.3) Si votre page ressemble à la mienne, elle affiche les erreurs de validation du modèle MAIS la page ne sera jamais rafraîchie après un envoi réussi, donc les erreurs de validation précédentes seront toujours affichées sur le formulaire. J'ai ajouté une ligne au gestionnaire d'événement submit du formulaire pour effacer les éléments enfants de n'importe quel élément avec la classe ".validation-summary-errors".