Classic WebForms and Excel - getting Couldn’t download – network issue when trying to download a generated Excel spreadsheet

Rod At Work 866 Reputation points
2021-08-16T16:57:13.507+00:00

I'm trying to use an old ASP.NET app, written using VB.NET by someone (not me) years ago. I've been tasked with maintaining it. It is an Intranet application used twice a year, for about 3 weeks each time. Employees enter data for 3 weeks, twice a year. After they've finished entering data, their managers generate reports, which are then used to report to funding sources. Most of the reports are written in Crystal Reports - they're all working fine. One report generates an Excel spreadsheet, which gets downloaded to the user's machine (a manager), to report to the funding source. It is this part which isn't working. When I run the report in Microsoft Edge, entering the parameters on the page that are then used in the generation of the Excel spreadsheet named Temp.xls, it fails with the error “Couldn’t download – network issue”. When I try using Google Chrome, I get the error "Failed - Network error". So, the same thing that MS Edge is giving me.

Last year I had to make some changes to the app. One of those changes was to the generation of the Excel spreadsheet. This is the code:

Response.ContentType = "application/vnd.ms-excel"  'This needed to be updated https://stackoverflow.com/questions/974079/setting-mime-type-for-excel-document

That changed worked well earlier this year when the app was used by the managers to generate the Excel spreadsheet. I'm now testing the app in preparation for the employees to start using next weekend. But now it doesn't work. It generates that network error.

Nothing has changed in the app since I modified it last year. The only changes that could have occurred would be changes to the server by some Windows update. I don't know where the error could be occurring. And networking isn't in my wheelhouse. I did try to narrow the problem down, by trying to run the report, then looking at both the web server's Event Viewer and my machine's Event Viewer for the timeframe when I was running the report. I looked in the Event Viewer's Windows Logs, the Application, Security and System logs. Both on the web server and my development machine. There were no errors related to this IIS app.

At this point I don't know how to proceed to try and determine why my browsers can't download the Temp.xls file that is being generated at the web server. I'd appreciate some guidance, please.

Internet Information Services
{count} votes

5 answers

Sort by: Most helpful
  1. Bruce Zhang-MSFT 3,751 Reputation points
    2021-08-27T03:22:01.97+00:00

    Hi @Rod At Work ,

    I will continue to discuss with you in this thread. There are three points that I think you need to confirm.

    1. Check MIME types on IIS. Make sure that .xls application/vdn.ms-excel exist in MIME types at the server and site level. This ensures that IIS allows such file transfers.126985-4.jpg
    2. Use Response.End() to replace Response.Close(). Response.Close sends a reset packet to the client and using it in anything other than error condition will lead to all sorts of problems - eg, if you are talking to a client with enough latency, the reset packet can cause any other response data buffered on the server, client or somewhere in between to be dropped.
    3. Use other browsers and try to download. Sometime network issue only report in chrome but other browsers can work well. IE, Edge and firefox are also great choices.
    4. When you removed the line that deletes the .xls file, does the file exist in folder?
    1 person found this answer helpful.

  2. MarkDsirl 1 Reputation point
    2021-09-23T15:50:37.697+00:00

    I think Access permission is for application pool. I saw website where mention these details. This might be works

    https://www.thedummyprogrammer.com/asp-net/configure-access-permission-to-a-folder-for-an-iis-application-pool

    For you.

    0 comments No comments

  3. AgaveJoe 28,876 Reputation points
    2021-08-27T12:34:41.417+00:00

    For some reason your other thread redirects here so my response is lost.

    Your code uses the file path on the server as the file name. You want the actual file name. Use the Path.GetFileName() method to grab the file name from the path.

    Response.AddHeader("Content-Disposition", "attachment; filename=" & Path.GetFileName(Fname))  
    

    Response.Close() can cause problems. The reference documentation recommends Response.End() or HttpContext.Current.ApplicationInstance.CompleteRequest()

    Response.ClearContent()  
    Response.ClearHeaders()  
    Response.ContentType = "application/vnd.ms-excel"  
    Response.AddHeader("Content-Disposition", "attachment; filename=" & Path.GetFileName(Fname))  
    WriteFile(Fname)  
    Response.End()  
    

    I'm pretty sure you not using ascyn methods correctly but it does not matter because execution never reaches DeleteTemporaryExportFileAsync() due to the Response.Close(). Secondly, there is no logical reason to implement an async method because the code is synchronous. Just delete the file once the WriteFile completes.

    Response.ClearContent()  
    Response.ClearHeaders()  
    Response.ContentType = "application/vnd.ms-excel"  
    Response.AddHeader("Content-Disposition", "attachment; filename=" & Path.GetFileName(Fname))  
    WriteFile(Fname)  
    File.Delete(Fname)  
    Response.End()  
    

    If you really want to implement an async delete then replace Response.End() with HttpContext.Current.ApplicationInstance.CompleteRequest()

    Lastly, I tested the WriteFile() method with a 350,000 KB using the updated code above and logic worked as expected. WriteFile() methods writes to the response stream in 300,000 byte blocks. Once the WriteFile() finished the file is deleted. Below is my test code.

    Public Class _Default11  
        Inherits System.Web.UI.Page  
      
        Dim Fname As String = "C:\Temp\largefile.xls"  
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load  
      
        End Sub  
      
        Protected Sub Button1_Click(sender As Object, e As EventArgs)  
            Response.ClearContent()  
            Response.ClearHeaders()  
            Response.ContentType = "application/vnd.ms-excel"  
            Response.AddHeader("Content-Disposition", "attachment; filename=" & Path.GetFileName(Fname))  
            WriteFile(Fname)  
            File.Delete(Fname)  
            Response.End()  
        End Sub  
      
        Private Sub WriteFile(ByVal Fname As String)  
      
            Dim MyFileInfo As FileInfo  
            Dim StartPos As Long = 0  
            Dim FileSize, ThisWrite, LeftToWrite As Long  
      
            MyFileInfo = New FileInfo(Fname)  
            FileSize = MyFileInfo.Length  
            LeftToWrite = FileSize  
      
            While LeftToWrite > 0  
                ThisWrite = IIf(LeftToWrite > 300000, 300000, LeftToWrite)  
                Response.WriteFile(Fname, StartPos, ThisWrite)  
                Response.Flush()  
                StartPos += ThisWrite  
                LeftToWrite -= ThisWrite  
            End While  
      
        End Sub  
      
      
    End Class  
    

    It would be very helpful if you can revert back to a code base that worked as expected. It's not clear if this bug is due to your updates or is an existing bug.

    1 person found this answer helpful.

  4. Rod At Work 866 Reputation points
    2021-08-17T16:02:43.853+00:00

    Testing. This editor doesn't seem to be working. It's rejected anything I've tried to add. Testing.

    0 comments No comments

  5. Rod At Work 866 Reputation points
    2021-08-17T16:12:35.4+00:00

    I've found how the Excel spreadsheet is created, so sort of solved one problem, but came up with another one. Here's the code as it was:

    Private Sub MakeExcel(ByVal withReport As ReportClass)
    
     Dim ps As WicReportBasics.ReportParameters = Session.Item("Parameters")
    
     'Dim tempDir As String = "c:\temp\"
     Dim tempDir As String = Common.GetTempDir()
    
     ' Write the xls file to a local directory temporarily
     Dim Fname As String = tempDir & Session.SessionID.ToString & ".xls"
     Dim DiskOptions As DiskFileDestinationOptions = New DiskFileDestinationOptions
     DiskOptions.DiskFileName = Fname
    
     Dim ExportOptions As ExportOptions = withReport.ExportOptions
     With ExportOptions
     .DestinationOptions = DiskOptions
     .ExportDestinationType = ExportDestinationType.DiskFile
     .ExportFormatType = ExportFormatType.Excel
     End With
     withReport.Export()
    
     ' The following code writes the excel file 
     ' to the Client’s browser.
     Response.ClearContent()
     Response.ClearHeaders()
     Response.ContentType = "application/vnd.ms-excel"  'This needed to be updated https://stackoverflow.com/questions/974079/setting-mime-type-for-excel-document
     Response.AddHeader("Content-Disposition", "attachment; filename=" & ps.OutputFileName & ".xls")
     WriteFile(Fname)
     Response.Close()
    
     ' delete the exported file from disk
     System.IO.File.Delete(Fname)
    
    End Sub
    

    The assigning of tempDir to Common.GetTempDir() was something I put in, some time back.

    Please note that I had made a mistake with the Response.AddHeader call. ps.OutputFileName returned "Temp". But as you can see, I'd created a different filename, so it couldn't find Temp.xls. I fixed that then tested it. It worked fine on my dev box. So, I published it to the web server. There it failed, again with a network error. I'm thinking the problem is with the System.IO.File.Delete(Fname) call that was put there by the original developer. That it was going too fast and deleting the .xls file before the browser had a chance to download it to the user's machine. So I changed it like so:

    Private Sub MakeExcel(ByVal withReport As ReportClass)
    
     Dim ps As WicReportBasics.ReportParameters = Session.Item("Parameters")
    
     'Dim tempDir As String = "c:\temp\"
     Dim tempDir As String = Common.GetTempDir()
    
     ' Write the xls file to a local directory temporarily
     Dim Fname As String = tempDir & Session.SessionID.ToString & ".xls"
     Dim DiskOptions As DiskFileDestinationOptions = New DiskFileDestinationOptions
     DiskOptions.DiskFileName = Fname
    
     Dim ExportOptions As ExportOptions = withReport.ExportOptions
     With ExportOptions
     .DestinationOptions = DiskOptions
     .ExportDestinationType = ExportDestinationType.DiskFile
     .ExportFormatType = ExportFormatType.Excel
     End With
     withReport.Export()
    
     ' The following code writes the excel file 
     ' to the Client’s browser.
     Response.ClearContent()
     Response.ClearHeaders()
     Response.ContentType = "application/vnd.ms-excel"  'This needed to be updated https://stackoverflow.com/questions/974079/setting-mime-type-for-excel-document
     'Response.AddHeader("Content-Disposition", "attachment; filename=" & ps.OutputFileName & ".xls")    'old way of handling the file
     Response.AddHeader("Content-Disposition", "attachment; filename=" & Fname)
     WriteFile(Fname)
     Response.Close()
    
     DeleteTemporaryExportFileAsync(Fname)
    End Sub
    
    Private Shared Async Sub DeleteTemporaryExportFileAsync(Fname As String)
     Await Task.Delay(5000)   'give the browser time to download the Excel spreadsheet
    
     Try
     ' delete the exported file from disk
     System.IO.File.Delete(Fname)
     Catch ex As Exception
     ' if the deletion fails, ignore it and move on
     End Try
    End Sub
    

    This gives a weird filename that looks something like this:

    C_Windows_Temp_hsnceshdnntdiul.xls

    Why has it changed the backslash character ("\") to an underscore, when run from the web server?


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.