0

We have the following ASP.NET code to download a CSV file from Response.Output.Write.

The iOS PWA (web app) downloads the file but provides no way back to the PWA app.

How can we avoid that 'no way back' page?

iOS PWA screen

Here is the code we have to download the CSV file:

 Private Function fCSVOutputCreateFile() As Boolean

    'Create the File Name
    Dim strFileName As String = ""
    Dim strFileNameZip As String = ""
    Dim strYearProxy As String = ""

    Select Case DropDownListDataName.SelectedValue           
        Case "Accounts"
        Case "Admins"           
        Case Else
            strYearProxy = "-" + DropDownListYear.SelectedValue.ToString
    End Select

    Dim bld1 As New StringBuilder
    With bld1
        .Append(strClsAppName)
        .Append("-")
        .Append(strClsUserType)
        .Append("-")
        .Append(lngClsUserTypeID.ToString)
        .Append("-")
        .Append(DropDownListDataName.SelectedItem.Text.Replace(" ", "-"))
        .Append(strYearProxy)
        .Append(".csv")

        strFileName = .ToString

    End With

    'Set compression option if given or auto-set
    If fAutoCompressRequired() = True Then
        Return False
    End If

    If CheckBoxCompressData.Checked = True Then

        'Create zip filename
        strFileNameZip = Left(strFileName, strFileName.Length - 4) + ".zip"

        'Compress and download
        Dim bytFile1 As Byte() = System.Text.Encoding.Unicode.GetBytes(strClsCSVOutputData)

        Using ms As MemoryStream = New MemoryStream()
            Using archive = New ZipArchive(ms, ZipArchiveMode.Create, True)
                Dim zipArchiveEntry = archive.CreateEntry(strFileName, CompressionLevel.Fastest)
                Using zipStream = zipArchiveEntry.Open()
                    zipStream.Write(bytFile1, 0, bytFile1.Length)
                End Using
            End Using

            'Response
            Response.Clear()
            Response.Buffer = True
            Response.ContentType = "application/octet-stream"
            Response.Headers.Add("Content-Disposition", "attachment; filename=" + strFileNameZip)

            ms.Seek(0, SeekOrigin.Begin)
            ms.WriteTo(Response.OutputStream)

            Response.Flush()
            Response.Close()
            Response.End()

        End Using

    Else

        'Download the CSV file
        Response.Clear()
        Response.Buffer = True
        Response.AddHeader("content-disposition", "attachment;filename=" + strFileName)
        Response.Charset = ""
        Response.ContentType = "application/text"
        Response.Output.Write(strClsCSVOutputData)
        Response.Flush()
        Response.End()

    End If

End Function

Any suggestions appreciated.

UPDATE 1:

I tried the suggestion shown in the comments by Andrew Morton but the IOS PWA still went to the same screen with no back ability, even though on the desktop it stayed on the same page.

~\pages\test\download\hdl1.ashx:

<%@ WebHandler Language="VB" Class="hdl1" %>

Imports System
Imports System.Web

Public Class hdl1 : Implements IHttpHandler

    Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest

        HttpContext.Current.Response.ClearContent()
        HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=1234.csv")
        HttpContext.Current.Response.ContentType = "application/text"
        HttpContext.Current.Response.Write("1a,2,3,4")

    End Sub

    Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
        Get
            Return False
        End Get
    End Property

End Class

~\pages\test\download\default.aspx:

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="default.aspx.vb" Inherits="pages_test_ashx_default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:LinkButton ID="LinkButton1" runat="server">Download</asp:LinkButton>
        </div>
    </form>
</body>
</html>

~\pages\test\download\default.aspx.vb

Partial Class pages_test_ashx_default
    Inherits System.Web.UI.Page

    Private Sub LinkButton1_Click(sender As Object, e As EventArgs) Handles LinkButton1.Click

        Response.Redirect("~/pages/test/download/hdl1.ashx")

    End Sub
End Class
user1946932
  • 474
  • 1
  • 16
  • 41
  • I wonder if the server.execute accepted answer at https://stackoverflow.com/questions/36171831/reponse-write-output-in-another-aspx-page may help – user1946932 Aug 25 '22 at 23:34
  • 1
    I guess that you are using a function on an aspx page to send the data. A better way is to use an ashx handler to send the data: [What is a Generic Handler in asp.net and its use?](https://stackoverflow.com/q/2332579/1115360). That way it stays on the same page. – Andrew Morton Aug 26 '22 at 17:37
  • @AndrewMorton Thanks. Please see UPDATE 1 in the question. – user1946932 Aug 28 '22 at 23:27
  • @AndrewMorton I've posted an answer below that allows going back. Does anyone know if the current backend code shown could be modified to do the same thing as that new JavaScript code does? That way we could keep it all in the backend and create that dynamic file name there there too. – user1946932 Aug 29 '22 at 02:22

1 Answers1

0
<script>

function fJDownloadCSV() {

var url = "https://www.oursite.com/pages/test/download/hdl1.ashx"

  var xhr = new XMLHttpRequest();
  xhr.open('GET', url, true);
  xhr.responseType = 'blob';
  xhr.onload = function(e) {
    if (this.status == 200) {
      var myBlob = this.response;
      var link = document.createElement('a');
      link.href = window.URL.createObjectURL(myBlob);
      link.download = "yourname.csv";
      link.click();
    }
  };
  xhr.send();
}

</script>

enter image description here

user1946932
  • 474
  • 1
  • 16
  • 41