locked
trying to allow users to download a dwg file to their pc from the webbrowser RRS feed

  • Question

  • User2009905846 posted

    I can get a PDF to show on the screen but I cannot get a DWG file to download to the PC. Please help. I am new to ASP.Net.

    int index = GridView.SelectedRow.RowIndex;
    string newFileName = selDocs[index];
    string fName = newFileName;
    FileInfo fi = new FileInfo(fName);
    string p = "http://internal.tech-etch.com:8081/datastore/" + fi.Name;
    
    if (newFileName.EndsWith(".pdf"))
    {
        HttpResponse response = HttpContext.Current.Response;
        response.Clear();
        response.BufferOutput = false;
        response.Redirect(p);
    
        response.Flush();
        HttpContext.Current.Response.Flush(); // Sends all currently buffered output to the client.
        HttpContext.Current.Response.SuppressContent = true;  // Gets or sets a value indicating whether to send HTTP content to the client.
        HttpContext.Current.ApplicationInstance.CompleteRequest(); // Causes ASP.NET to bypass all events and filtering in the HTTP pipeline chain of execution and directly execute the EndRequest event.
    }
    else if (newFileName.EndsWith(".dwg"))
    {
        // -- if the file exists on the server
        try
        {
            var fileToDownload = "internal.tech-etch.com:8081/datastore/" + fi.Name;
            HttpResponse response = HttpContext.Current.Response;
            response.ContentType = "application/octet-stream";
            var cd = new ContentDisposition
            {
                Inline = false,
                FileName = Path.GetFileName(fileToDownload)
            };
            response.AppendHeader("Content-Disposition", cd.ToString());
    
            byte[] fileData = System.IO.File.ReadAllBytes(fileToDownload);
            response.OutputStream.Write(fileData, 0, fileData.Length);
            HttpContext.Current.Response.Flush(); // Sends all currently buffered output to the client.
            HttpContext.Current.Response.SuppressContent = true;  // Gets or sets a value indicating whether to send HTTP content to the client.
            HttpContext.Current.ApplicationInstance.CompleteRequest(); // Causes ASP.NET to bypass all events and filtering in the HTTP pipeline chain of execution and directly execute the EndRequest event.
        }
        catch (Exception ex)
        {
            string message = string.Format("Try block failed. newFileName: {0}, fName: {1}, p: {2}, ex: {3}", newFileName, fName, p, ex);
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            sb.Append("<script type = 'text/javascript'>");
            sb.Append("window.onload=function(){");
            sb.Append("alert('");
            sb.Append(message);
            sb.Append("')};");
            sb.Append("</script>");
            ClientScript.RegisterClientScriptBlock(this.GetType(), "alert", sb.ToString());
        }
    }
    

    Thursday, October 10, 2019 8:51 PM

Answers

  • User-719153870 posted

    Hi jaktechie,

    but I cannot get a DWG file to download to the PC

    I tested your code and it worked perfectly, my guess is that your dwg file paht might be incorrect.

    Please put several breakpoints around below code and debug to see if you can get the right fileToDownload path:

    var fileToDownload = "internal.tech-etch.com:8081/datastore/" + fi.Name;

    Usually, we don't need to write a file path like this, a relative address is enough. for example,

    var fileToDownload = "/datastore/" + fi.Name;

    Also, you can refer to below demo which built based on your code and changed a little places wo fit my invironment, i have highlighted the place where i made a change:

    protected void Button1_Click(object sender, EventArgs e)
            {
                try
                {
                    var fileToDownload = "files/testwdg.dwg";
                    HttpResponse response = HttpContext.Current.Response;
                    response.ContentType = "application/octet-stream";
                    var cd = new ContentDisposition
                    {
                        Inline = false,
                        FileName = Path.GetFileName(fileToDownload)
                    };
                    response.AppendHeader("Content-Disposition", cd.ToString());
    
                    byte[] fileData = System.IO.File.ReadAllBytes(fileToDownload);
                    response.OutputStream.Write(fileData, 0, fileData.Length);
                    HttpContext.Current.Response.Flush(); // Sends all currently buffered output to the client.
                    HttpContext.Current.Response.SuppressContent = true;  // Gets or sets a value indicating whether to send HTTP content to the client.
                    HttpContext.Current.ApplicationInstance.CompleteRequest(); // Causes ASP.NET to bypass all events and filtering in the HTTP pipeline chain of execution and directly execute the EndRequest event.
                }
                catch (Exception ex)
                {
                    string message = string.Format("Try block failed. newFileName: {0}, fName: {1}, p: {2}, ex: {3}", "newFileName", "fName", "p", ex);
                    System.Text.StringBuilder sb = new System.Text.StringBuilder();
                    sb.Append("<script type = 'text/javascript'>");
                    sb.Append("window.onload=function(){");
                    sb.Append("alert('");
                    sb.Append(message);
                    sb.Append("')};");
                    sb.Append("</script>");
                    ClientScript.RegisterClientScriptBlock(this.GetType(), "alert", sb.ToString());
                }
            }

    Best Rgard,

    Yang Shen

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, October 11, 2019 6:17 AM

All replies

  • User-719153870 posted

    Hi jaktechie,

    but I cannot get a DWG file to download to the PC

    I tested your code and it worked perfectly, my guess is that your dwg file paht might be incorrect.

    Please put several breakpoints around below code and debug to see if you can get the right fileToDownload path:

    var fileToDownload = "internal.tech-etch.com:8081/datastore/" + fi.Name;

    Usually, we don't need to write a file path like this, a relative address is enough. for example,

    var fileToDownload = "/datastore/" + fi.Name;

    Also, you can refer to below demo which built based on your code and changed a little places wo fit my invironment, i have highlighted the place where i made a change:

    protected void Button1_Click(object sender, EventArgs e)
            {
                try
                {
                    var fileToDownload = "files/testwdg.dwg";
                    HttpResponse response = HttpContext.Current.Response;
                    response.ContentType = "application/octet-stream";
                    var cd = new ContentDisposition
                    {
                        Inline = false,
                        FileName = Path.GetFileName(fileToDownload)
                    };
                    response.AppendHeader("Content-Disposition", cd.ToString());
    
                    byte[] fileData = System.IO.File.ReadAllBytes(fileToDownload);
                    response.OutputStream.Write(fileData, 0, fileData.Length);
                    HttpContext.Current.Response.Flush(); // Sends all currently buffered output to the client.
                    HttpContext.Current.Response.SuppressContent = true;  // Gets or sets a value indicating whether to send HTTP content to the client.
                    HttpContext.Current.ApplicationInstance.CompleteRequest(); // Causes ASP.NET to bypass all events and filtering in the HTTP pipeline chain of execution and directly execute the EndRequest event.
                }
                catch (Exception ex)
                {
                    string message = string.Format("Try block failed. newFileName: {0}, fName: {1}, p: {2}, ex: {3}", "newFileName", "fName", "p", ex);
                    System.Text.StringBuilder sb = new System.Text.StringBuilder();
                    sb.Append("<script type = 'text/javascript'>");
                    sb.Append("window.onload=function(){");
                    sb.Append("alert('");
                    sb.Append(message);
                    sb.Append("')};");
                    sb.Append("</script>");
                    ClientScript.RegisterClientScriptBlock(this.GetType(), "alert", sb.ToString());
                }
            }

    Best Rgard,

    Yang Shen

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, October 11, 2019 6:17 AM
  • User2009905846 posted

    Thank you for the quick response Yang Shen. I made your suggestion but I am still having the error. The file dialog appears and the file looks correct but the file is corrupted. I can open the file manually.

    Here is my revised code: In my testing 'newFileName' would equal '"\\\\tech-web\\QC_Databasefiles\\CAD_PE1008_LegacyArc1.dwg"

    If I try something like: http://internal.tech-etch.com:8081/datastore/Draw_PE1008.pdf in my browser it will open the pdf file.

    FileInfo fi = new FileInfo(newFileName);
    string fileToDownload = @"~/datastore/" + fi.Name;
    
    if (newFileName.EndsWith(".pdf"))
    {
       HttpResponse response = HttpContext.Current.Response;
       response.Clear();
       response.BufferOutput = false;
       response.Redirect(fileToDownload);
    
       response.Flush();
       HttpContext.Current.Response.Flush();
       HttpContext.Current.Response.SuppressContent = true;
       HttpContext.Current.ApplicationInstance.CompleteRequest();
    }
    else if (newFileName.EndsWith(".dwg"))
    {
       try
       {
          HttpResponse response = HttpContext.Current.Response;
          response.ContentType = "application/octet-stream";
          var cd = new ContentDisposition
          {
             Inline = false,
             FileName = Path.GetFileName(fileToDownload)
          };
          response.AppendHeader("Content-Disposition", cd.ToString());
          
          byte[] fileData = System.IO.File.ReadAllBytes(fileToDownload);
          response.OutputStream.Write(fileData, 0, fileData.Length);
          HttpContext.Current.Response.Flush();
          HttpContext.Current.Response.SuppressContent = true;
          HttpContext.Current.ApplicationInstance.CompleteRequest();
       }
       catch (Exception ex)
       {
          Alert(string.Format("Debug: Try block failed. newFileName: {0}, fileToDownload: {1}, fileName: {2}, ex: {3}", newFileName, fileToDownload, Path.GetFileName(fileToDownload), ex));
       }
    
    }

    Friday, October 11, 2019 1:04 PM
  • User753101303 posted

    Hi,

    Maybe a permission issue. The account used by your app needs a read access to the network share you are using.

    What does Alert? What if you look at the file content ? I suspect that for now you are writing an error message to the browser. IMO the current exception handling approach is not convenient. I would get rid of it for now.

    Friday, October 11, 2019 1:49 PM
  • User2009905846 posted

    PatriceSc I agree it is probably a permission issue.

    Alert just sends an alert showing text for debugging.

    I have a temporary solution of moving the data to the same directory as the app in its own folder. I am able to do what I need to for now.

    Thank you all for your help

    Friday, October 11, 2019 2:03 PM
  • User753101303 posted

    "sends an alert" but how? Have you tried to look at the downloaded content with notepad ?

    I suspect that alerts doesn't reset the response and that you end up in downloading the error message as the content of this file...

    Friday, October 11, 2019 2:59 PM
  • User2009905846 posted

    "sends an alert" but how? Have you tried to look at the downloaded content with notepad ?

    I suspect that alerts doesn't reset the response and that you end up in downloading the error message as the content of this file...

    'sends an alert' is just code that will pop up an alert messagebox. That is for debugging. That works fine and does not impact my file download.

            ..........
            catch (Exception ex)
            {
                Alert(string.Format("Debug: Try block failed. newFileName: {0}, fileToDownload: {1}, fileName: {2}, ex: {3}", newFileName, fileToDownload, Path.GetFileName(fileToDownload), ex));
            }
        }
    }
    
    private void Alert(string msg)
    {
        System.Text.StringBuilder sb = new System.Text.StringBuilder();
        sb.Append("");
        ClientScript.RegisterClientScriptBlock(this.GetType(), "alert", sb.ToString());
    }

    Friday, October 11, 2019 3:28 PM
  • User753101303 posted

    does not impact my file download

    What I'm trying to tell is that if an exception happens after you sent the content disposition header, you end up in sending this exception message to the browser rather than the actual file content and as a result it seems the file is "corrupted".

    This is why I suggested to open the downloaded file with notepad so that you can look at its content.

    If not that at least this door is now closed and you can go to plan B.

    If this is that,  you'll know for sure which problem happens and it should be then much easier to fix your issue (even if moving the file really points at a problem in using the network share likely because of a permission problem).

    Friday, October 11, 2019 4:23 PM