Ce que j'ai?
J'ai une page ASP.NET qui permet à l'utilisateur de télécharger le fichier a
sur un clic de bouton. L'utilisateur peut sélectionner le fichier qu'il souhaite dans une liste de fichiers disponibles (RadioButtonList) et cliquer sur le bouton de téléchargement pour le télécharger. (Je ne devrais pas fournir de lien pour chaque fichier pouvant être téléchargé - c'est l'exigence).
Ce que je veux?
Je veux que l'utilisateur télécharge plusieurs fichiers un par un en sélectionnant le bouton radio requis et en cliquant sur le bouton.
À quel problème suis-je confronté?
Je peux télécharger le fichier pour la première fois correctement. Mais, après le téléchargement, si je sélectionne un autre fichier et clique sur le bouton pour le télécharger, cliquez sur l'événement du bouton ne s'affiche pas et le second fichier ne sera pas téléchargé.
J'utilise le code suivant sur l'événement de clic de bouton:
protected void btnDownload_Click(object sender, EventArgs e)
{
string viewXml = exporter.Export();
Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=views.cov");
Response.AddHeader("Content-Length", viewXml.Length.ToString());
Response.ContentType = "text/plain";
Response.Write(viewXml);
Response.End();
}
Est-ce que je fais quelque chose de mal ici?
Le même problème peut être répliqué dans IE6, IE7 et Chrome. Je pense que ce problème est indépendant du navigateur.
J'ai eu le même problème avec SharePoint. J'ai un bouton sur la page qui envoie un fichier et après avoir cliqué sur le bouton, le reste du formulaire ne répondait plus. Il s'avère que c'est un point de partage qui définit la variable _spFormOnSubmitCalled sur true pour empêcher toute soumission ultérieure Lorsque nous envoyons un fichier, la page n'est pas actualisée, nous devons donc redéfinir manuellement cette variable sur false.
Sur votre bouton dans la Webpart, définissez OnClientClick sur une fonction de votre javascript pour la page.
<asp:Button ID="generateExcel" runat="server" Text="Export Excel"
OnClick="generateExcel_Click" CssClass="rptSubmitButton"
OnClientClick="javascript:setFormSubmitToFalse()" />
Ensuite, dans le javascript, j'ai cette fonction.
function setFormSubmitToFalse() {
setTimeout(function () { _spFormOnSubmitCalled = false; }, 3000);
return true;
}
La pause de 3 secondes que j'ai trouvée était nécessaire car sinon, je définissais la variable avant que sharepoint ne la définisse. De cette façon, je laisse sharepoint le régler normalement, puis je le remets à False juste après.
Un moyen simple de le faire sans supprimer Response.End
consiste à ajouter un js côté client pour actualiser la page. Ajoutez le js à la propriété onclientclick de votre bouton.
par exemple.
onclientclick="timedRefresh(2000)"
then in your html..
<script type="text/JavaScript">
<!--
function timedRefresh(timeoutPeriod) {
setTimeout("location.reload(true);",timeoutPeriod);
}
// -->
De prime abord, ce que vous faites devrait fonctionner. J'ai réussi à faire la même chose dans le passé, bien que j'aie utilisé un répéteur et des LinkButtons.
La seule chose qui me distingue, c'est que vous utilisez Response.Write()
plutôt que Response.OutputStream.Write()
et que vous écrivez du texte plutôt que du binaire, mais étant donné la ContentType
que vous avez spécifiée, cela ne devrait pas poser de problème. De plus, j'appelle Response.ClearHeaders()
avant d'envoyer des informations et Response.Flush()
après (avant mon appel à Response.End()
).
Si cela peut vous aider, voici une version assainie de ce qui fonctionne bien pour moi:
// called by click handler after obtaining the correct MyFileInfo class.
private void DownloadFile(MyFileInfo file)
{
Response.Clear();
Response.ClearHeaders();
Response.ContentType = "application/file";
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + file.FileName + "\"");
Response.AddHeader("Content-Length", file.FileSize.ToString());
Response.OutputStream.Write(file.Bytes, 0, file.Bytes.Length);
Response.Flush();
Response.End();
}
Vous voudrez peut-être envisager de transférer le fichier de manière binaire, par exemple en appelant System.Text.Encoding.ASCII.GetBytes(viewXml);
et en transmettant le résultat de celui-ci à Response.OutputStream.Write()
.
Modifier légèrement votre code:
protected void btnDownload_Click(object sender, EventArgs e)
{
string viewXml = exporter.Export();
byte [] bytes = System.Text.Encoding.ASCII.GetBytes(viewXml);
// NOTE: you should use whatever encoding your XML file is set for.
// Alternatives:
// byte [] bytes = System.Text.Encoding.UTF7.GetBytes(viewXml);
// byte [] bytes = System.Text.Encoding.UTF8.GetBytes(viewXml);
Response.Clear();
Response.ClearHeaders();
Response.AddHeader("Content-Disposition", "attachment; filename=views.cov");
Response.AddHeader("Content-Length", bytes.Length.ToString());
Response.ContentType = "application/file";
Response.OutputStream.Write(bytes, 0, bytes.Length);
Response.Flush();
Response.End();
}
J'ai eu le même problème. Fonction permettant d’exécuter Response.Writer ("") simple lorsqu’un clic sur un bouton de la page aspx ne s’est jamais déclenché.
Méthode en classe:
public test_class()
{
public test_class() { }
public static void test_response_write(string test_string)
{
HttpContext context = HttpContext.Current;
context.Response.Clear();
context.Response.Write(test_string);
context.Response.End();
}
}
Page ASPX:
protected void btn_test_Click(object sender, EventArgs e)
{
test_class.test_response_write("testing....");
}
Pendant que j'essayais de trouver la raison, je venais d'appeler la même fonction sur l'événement Page_Load
qui fonctionnait.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
test_class.test_response_write("testing....");
}
}
En examinant le problème, j'ai découvert que Master Page du corps de cette page aspx était placé sous <asp:UpdatePanel>
.
Je l'ai enlevé, et cela a fonctionné sur Button_Click
Event. Je vous recommanderais de vérifier cela aussi.
Supprimez Response.End()
et laissez la réponse se terminer naturellement dans l'écosystème ASP.NET.
Si cela ne fonctionne pas, je vous recommande de placer le bouton dans un <form>
séparé et d'envoyer les données requises dans un gestionnaire HTTP distinct. Configurez le gestionnaire HTTP pour exporter le XML au lieu d’une page Web.
Vérifiez sur https://multilingualdev.wordpress.com/2014/08/19/asp-net-postback-after-response-write-work-around-solution/
Lors de l'envoi d'un fichier au client et de l'utilisation de response.write dans ASP.Net, le développeur ne peut plus rien faire après l'envoi du fichier. Il existe d’autres solutions telles que l’ajout d’une fonction javascript onclick qui appelle une fonction après que le client a récupéré le fichier. Actualiser ”,“ 5; URL = ”& HttpContext.Current.Request.Url.AbsoluteUri))
Mais ceux-ci ne me donnaient pas le regard que je voulais. J'ai donc utilisé une combinaison de ces solutions pour proposer cette solution:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
checkSendFile() ‘each time page loads it will check to see if it needs to send the file
If (Not IsPostBack) Then
‘this spot is not be executed after a form submit (postback); which means you can put
‘ the checkSendFile() in here if you want
end If
End Sub
Private Sub checkSendFile()
Dim sendFile As String = Session(“SENDFILE”) ‘ first we get the session file to see if its time
‘ to send a file
If Not sendFile Is Nothing Then
If sendFile = “YES” Then
Session(“SENDFILE”) = “” ‘here we clear the session file so it doesn’t send again if
‘ refreshed
sendClientFile() ‘ function to send the file to client
End If
End If
End Sub
Protected Sub btnGetFile_Click(sender As Object, e As EventArgs) Handles btnGetFile.Click
‘this is where the client clicks on a button or link or something that submits the form and
‘ request a file to be sent to them
Session(“SENDFILE”) = “YES” ‘ we set a session variable flag
‘then we update the GUI, or run any other method that we wanted to do after client gets file
me.lblMsgToClient.text = “Thank you for downloading file.”
RefreshPage() ‘ then we refresh the page instantly (this is where post back will update values
‘ and interface, then send file)
End Sub
Private Sub RefreshPage()
‘ here we instantly add a refresh meta tag to the header with zero seconds to refresh to the
‘ same url we are currently at
Response.AppendHeader(“Refresh”, “0;URL=” & HttpContext.Current.Request.Url.AbsoluteUri)
End Sub
Private Sub sendClientFile()
‘here you will have your file and bytes to send to browser from either file system or database
‘then you can call sendToBrowser(…)
End Sub
Private Sub sendToBrowser(ByVal fileName As String, ByVal contentType As String, ByRef fileBytes As Byte())
‘this function is just the normal send file to client
Response.AddHeader(“Content-type”, contentType)
Response.AddHeader(“Content-Disposition”, “attachment; filename=” & fileName)
Response.BinaryWrite(fileBytes)
Response.Flush()
Response.End()
End Sub