Solved

Save a ASPX page to file/disk

Posted on 2004-04-30
16
633 Views
Last Modified: 2008-01-16
People using my tool via WEB need to save the .aspx page to disk and see it to another pc (offline).
So, imagine that the user sees a page.aspx, that is a report containing only stupid html, now I'm looking for something like
- user clicks a button
- a offline version of page.aspx (pageoff.html) is send as file to the user


Is it possible?
Thanks
0
Comment
Question by:r79abc
  • 6
  • 6
  • 4
16 Comments
 
LVL 4

Expert Comment

by:Kittrick
ID: 10963191
If they did save it to their computers for running remember that they would have to install the .net framework and IIS if they even have it at all...as an aspx page is compiled at runtime by the .net framework. Otherwise they could just go to file--> save as in their browser
0
 
LVL 4

Expert Comment

by:Kittrick
ID: 10963202
you could also look into making your app a webservice, so it eliminates the hassle of everyone having a copy because it would run off your server.
0
 
LVL 4

Expert Comment

by:Kittrick
ID: 10963213
if it's a report, they could even copy and paste it to excel
0
 
LVL 4

Expert Comment

by:Kittrick
ID: 10963225
from the webpage itself I mean. Sorry I posted several times...I have ideas flowing.
0
 
LVL 12

Expert Comment

by:esteban_felipe
ID: 10965481
Hi r79abc,

All you need to do is to call Page.Render and pass it a Html32TextWriter that's under your control. That's exactly what the framework does. Check out this sample (in C#.. i don't do VB)

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.IO;
namespace WebApplication1
{
      public class WebForm1 : System.Web.UI.Page
      {
            protected System.Web.UI.WebControls.Button Button1;
            protected System.Web.UI.WebControls.Label Label1;
      
            private void Page_Load(object sender, System.EventArgs e)
            {
                  if(!Page.IsPostBack)
                  {
                        Label1.Text="Hello world!";
                  }
            }

            #region Web Form Designer generated code
            override protected void OnInit(EventArgs e)
            {
                  //
                  // CODEGEN: This call is required by the ASP.NET Web Form Designer.
                  //
                  InitializeComponent();
                  base.OnInit(e);
            }
            
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {    
                  this.Button1.Click += new System.EventHandler(this.Button1_Click);
                  this.Load += new System.EventHandler(this.Page_Load);

            }
            #endregion

            private void Button1_Click(object sender, System.EventArgs e)
            {
                  Button1.Visible = false;
                  MemoryStream renderedPage = new MemoryStream();
                  Html32TextWriter myWriter = new Html32TextWriter(new StreamWriter(renderedPage));
                  this.Render(myWriter);
                  myWriter.Close();
                  Response.Clear();
                  Response.AddHeader("Content-Disposition", "attachment; filename=yourpage.html");
                  Response.ContentType = "applicationoctet-stream";
                  Response.BinaryWrite(renderedPage.GetBuffer());
                  Response.End();
            }
      }
}

Just a final advice. Don't use Response.Write in the page you want to be rendered-downloadable. I hope this could help. Good luck

Esteban Felipe
www.estebanf.com
0
 
LVL 12

Expert Comment

by:esteban_felipe
ID: 10965485
r79abc,

Here's the HMTL of that page:

<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="WebApplication1.WebForm1" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
      <HEAD>
            <title>WebForm1</title>
            <meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
            <meta name="CODE_LANGUAGE" Content="C#">
            <meta name="vs_defaultClientScript" content="JavaScript">
            <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
      </HEAD>
      <body MS_POSITIONING="GridLayout">
            <form id="Form1" method="post" runat="server">
                  <asp:Label id="Label1" style="Z-INDEX: 101; LEFT: 8px; POSITION: absolute; TOP: 8px" runat="server">Label</asp:Label>
                  <asp:Button id="Button1" style="Z-INDEX: 102; LEFT: 16px; POSITION: absolute; TOP: 56px" runat="server"
                        Text="Get Rendered page without this button"></asp:Button>
            </form>
      </body>
</HTML>


Esteban Felipe
www.estebanf.com
0
 

Author Comment

by:r79abc
ID: 10969624
That is really nice code. It works really well.
But:
- in my code there are images (from webchart graph dll) and these (at least the link) are not copied
- A used things like Panel1.Controls.Add ( new Label .... ) and the result is not visible.

Is it possible to solve also these problems?
Thanks




-------------- Here there is your code modified
<%@ Page Language="C#" autoeventwireup="false" %>
<%@ Register TagPrefix="Web" Namespace="WebChart" Assembly="WebChart, Version=1.1.1.3, Culture=neutral, PublicKeyToken=eac822d9c4196ba1" %>
<%@ import Namespace="System" %>
<%@ import Namespace="System.Collections" %>
<%@ import Namespace="System.ComponentModel" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="System.Drawing" %>
<%@ import Namespace="System.Web" %>
<%@ import Namespace="System.Web.SessionState" %>
<%@ import Namespace="System.Web.UI" %>
<%@ import Namespace="System.Web.UI.WebControls" %>
<%@ import Namespace="System.Web.UI.HtmlControls" %>
<%@ import Namespace="System.IO" %>
<script runat="server">

    private void Page_Load(object sender, System.EventArgs e)
    {
         if(!Page.IsPostBack)
         {
              Label1.Text="Hello world!";
                ColumnChart chart = new ColumnChart();
   
                chart.Fill.Color = Color.FromArgb(50, Color.SteelBlue);
                chart.Line.Color = Color.SteelBlue;
                chart.Line.Width = 2;
   
                chart.Legend = "WebChart information";
                chart.Data.Add( new ChartPoint("Jan", 10) );
   
                ChartControl1.Charts.Add(chart);
                ChartControl1.RedrawChart();
   
                Label l2=new Label();
                l2.Text = "TEST";
                Panel1.Controls.Add(l2);
         }
    }
   
    #region Web Form Designer generated code
    override protected void OnInit(EventArgs e)
    {
         //
         // CODEGEN: This call is required by the ASP.NET Web Form Designer.
         //
         InitializeComponent();
         base.OnInit(e);
    }
   
    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
         this.Button1.Click += new System.EventHandler(this.Button1_Click);
         this.Load += new System.EventHandler(this.Page_Load);
   
    }
    #endregion
   
    private void Button1_Click(object sender, System.EventArgs e)
    {
         Button1.Visible = false;
         MemoryStream renderedPage = new MemoryStream();
         Html32TextWriter myWriter = new Html32TextWriter(new StreamWriter(renderedPage));
         this.Render(myWriter);
         myWriter.Close();
         Response.Clear();
         Response.AddHeader("Content-Disposition", "attachment; filename=yourpage.html");
         Response.ContentType = "applicationoctet-stream";
         Response.BinaryWrite(renderedPage.GetBuffer());
         Response.End();
    }

</script>
<html>
<head>
    <title>WebForm1</title>
    <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR" />
    <meta content="C#" name="CODE_LANGUAGE" />
    <meta content="JavaScript" name="vs_defaultClientScript" />
    <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema" />
</head>
<body ms_positioning="GridLayout">
    <form id="Form1" method="post" runat="server">
        <p>
            <asp:Label id="Label1" style="Z-INDEX: 101; LEFT: 550px; POSITION: absolute; TOP: 281px" runat="server">Label</asp:Label>
            <asp:Button id="Button1" style="Z-INDEX: 102; LEFT: 64px; POSITION: absolute; TOP: 407px" runat="server" Text="Get Rendered page without this button"></asp:Button>
            <Web:ChartControl id="ChartControl1" runat="Server" Width="500" Height="350"></Web:ChartControl>
            <asp:Panel id="Panel1" runat="server">Panel</asp:Panel>
        </p>
    </form>
</body>
</html>

0
 

Author Comment

by:r79abc
ID: 10969625
Used all points...
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

Author Comment

by:r79abc
ID: 10971546
I've seen that I need to ovveride the render for all control inserted on the page... but I've no idea of what it means...
0
 
LVL 12

Expert Comment

by:esteban_felipe
ID: 10972436
no... you don-t need to override nothing... just call Page.Render with your own Html32Writer.... my sample should work with any page.
0
 

Author Comment

by:r79abc
ID: 10973143
I konw that your example works well.
BUT when I write something like

Label l2=new Label();
l2.Text = "TEST";
Panel1.Controls.Add(l2);

then Button1_Click function doen't display in .html document the label2

Why? There is a soluton?
0
 
LVL 12

Expert Comment

by:esteban_felipe
ID: 10973251
are you doing that in the same request than button1_click?. If not your problem is about dinamic controls created at runtime. Those controls are not stored between postbacks automaticly, so you will have to do it yourself.
0
 

Author Comment

by:r79abc
ID: 10973310
Sorry, I'm a newbie...
This is your code that I've modified..
Label2 is not displayed.. could you give me the final help?

---------------
<%@ Page Language="C#" autoeventwireup="false" %>
<%@ import Namespace="System" %>
<%@ import Namespace="System.Collections" %>
<%@ import Namespace="System.ComponentModel" %>
<%@ import Namespace="System.Data" %>
<%@ import Namespace="System.Drawing" %>
<%@ import Namespace="System.Web" %>
<%@ import Namespace="System.Web.SessionState" %>
<%@ import Namespace="System.Web.UI" %>
<%@ import Namespace="System.Web.UI.WebControls" %>
<%@ import Namespace="System.Web.UI.HtmlControls" %>
<%@ import Namespace="System.IO" %>
<script runat="server">

    private void Page_Load(object sender, System.EventArgs e)
         {
              if(!Page.IsPostBack)
              {
                   Label1.Text="Hello world!";
                   Label l2=new Label();
                   l2.Text = "THIS SHOULD BE DISPLAYED ALSO IN yourpage.html ";
                   Panel1.Controls.Add(l2);
              }
         }

         #region Web Form Designer generated code
         override protected void OnInit(EventArgs e)
         {
              //
              // CODEGEN: This call is required by the ASP.NET Web Form Designer.
              //
              InitializeComponent();
              base.OnInit(e);
         }

         /// <summary>
         /// Required method for Designer support - do not modify
         /// the contents of this method with the code editor.
         /// </summary>
         private void InitializeComponent()
         {
              this.Button1.Click += new System.EventHandler(this.Button1_Click);
              this.Load += new System.EventHandler(this.Page_Load);

         }
         #endregion

         private void Button1_Click(object sender, System.EventArgs e)
         {
              Button1.Visible = false;
              MemoryStream renderedPage = new MemoryStream();
              Html32TextWriter myWriter = new Html32TextWriter(new StreamWriter(renderedPage));
              this.Render(myWriter);
              myWriter.Close();
              Response.Clear();
              Response.AddHeader("Content-Disposition", "attachment; filename=yourpage.html");
              Response.ContentType = "applicationoctet-stream";
              Response.BinaryWrite(renderedPage.GetBuffer());
              Response.End();
         }

</script>
<html>
<head>
    <title>WebForm1</title>
    <meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR" />
    <meta content="C#" name="CODE_LANGUAGE" />
    <meta content="JavaScript" name="vs_defaultClientScript" />
    <meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema" />
</head>
<body ms_positioning="GridLayout">
    <form id="Form1" method="post" runat="server">
        <p>
            <asp:Label id="Label1" style="Z-INDEX: 101; LEFT: 240px; POSITION: absolute; TOP: 23px" runat="server">Label</asp:Label>
            <asp:Button id="Button1" style="Z-INDEX: 102; LEFT: 28px; POSITION: absolute; TOP: 117px" runat="server" Text="Get Rendered page without this button"></asp:Button>
            <asp:Panel id="Panel1" runat="server">Panel</asp:Panel>
        </p>
    </form>
</body>
</html>
0
 
LVL 12

Accepted Solution

by:
esteban_felipe earned 135 total points
ID: 10973330
get:

 Label l2=new Label();
                   l2.Text = "THIS SHOULD BE DISPLAYED ALSO IN yourpage.html ";
                   Panel1.Controls.Add(l2);

out of the if(!Page.IsPostback) block

then it will work
0
 

Author Comment

by:r79abc
ID: 10973358
OK.. it works.
There are others task opened..For example if the page has an image.. what I need to do?

But or now it's enough.. (but.. if u have a quick solution.. you are welcome!)
Anyway you did for me a great work.


Thank you!
0
 
LVL 12

Expert Comment

by:esteban_felipe
ID: 10973382
ohh... with images it will be much harder. I can think in several solutions but none it's easy. You will need to produce your rendered html page, then will need to parse it to find the images tags, transform them to target local images and include those images in your download (maybe in a zip file).... Another approach that I would take would be to use a commercial or open source component to generate pdf files with my report. Maybe this way is more expensive, but i'm sure it will be easier...
0

Featured Post

Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

Join & Write a Comment

This article discusses the ASP.NET AJAX ModalPopupExtender control. In this article we will show how to use the ModalPopupExtender control, how to display/show/call the ASP.NET AJAX ModalPopupExtender control from javascript, how to show/display/cal…
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now