View Full Version : .net: How to include the contents of one aspx page in another?
david7777
05-05-2003, 04:12 PM
I am trying to create the best navigation system fo my site.
First of all - any suggestions on the best way?
I have the idea of using a main.aspx page as a template, and passing the page i want displayed like this: main.aspx?p=default
Then in the code of main.aspx i will have the menu set up and ready, and want to include the contents of "default.aspx" in the page.
So for instance - main.aspx?p=default is called.
main.aspx has a table with a menu on the side, and and a footer. The main part of the page is blank for the body.
I will get the name of the page requested - ie: default.
I will only use .aspx files, so therefore, default.aspx.
Now include default.aspx in the allocated section of the table in main.aspx. eg: <!--#include file="default.aspx" -->(I know that way wont work - just an example)
How do i do that?
Keep in mind that .aspx files are being used, so the server side code must be run before displayed...
angiras
05-05-2003, 07:04 PM
for the moment you have two good way to do a kinds of page Template
1)
class basePage : inherits Page
the your pages will not inherits Page but basePage
2)
you do a template.ascx inherits userControl
with all your page in it and you load it
this second way (which is not mine)is developped by microsfot as masterPages
----------------------
an exemple of inheritance :
Namespace heritage
Public MustInherit Class pageTemplate : Inherits Page
Protected form As HtmlForm
Sub New()
MyBase.new()
form = New HtmlForm()
form.ID = "frm"
End Sub
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
End Sub
Protected Overrides Sub AddParsedSubObject(ByVal obj As Object)
form.Controls.Add(CType(obj, Control))
End Sub
Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
EnsureChildControls()
Me.Controls.Add(form)
End Sub
Protected Overrides Sub Render(ByVal w As System.Web.UI.HtmlTextWriter)
w.WriteLine("<?xml version=""1.0"" encoding=""iso-8859-1""?>")
w.WriteLine("<!DOCTYPE html PUBLIC ""-//W3C//DTD XHTML 1.0 Transitional//EN"" ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"">")
w.WriteLine("<html xmlns=""http://www.w3.org/1999/xhtml"" xml:lang=""fr"">")
w.WriteLine("<head>")
w.WriteLine("<meta http-equiv=""Content-Type"" content=""text/html; charset=iso-8859-1"" />")
w.WriteLine(metasTags.metas)
w.WriteLine("</head>")
w.WriteLine("<body>")
MyBase.Render(w)
w.WriteLine("</body>")
w.WriteLine("</html>")
End Sub
End Class
Public Module metasTags
Private _title As String
Private _keywords As String
Private _description As String
Private _metas As String = "<title>{0}</title><meta name=""keywords"" content=""{1}"" /><meta name=""description"" content=""{2}"" />"
Public ReadOnly Property metas() As String
Get
sb = New StringBuilder()
sb.AppendFormat(_metas, title, keywords, description)
Return sb.ToString
End Get
End Property
Public Property title() As String
Get
Return _title
End Get
Set(ByVal Value As String)
_title = Value
End Set
End Property
Public Property keywords() As String
Get
Return _keywords
End Get
Set(ByVal Value As String)
_keywords = Value
End Set
End Property
Public Property description() As String
Get
Return _description
End Get
Set(ByVal Value As String)
_description = Value
End Set
End Property
End Module
End Namespace
default.aspx
<%@ Page Codebehind="default.aspx.vb" Inherits="test.masterPage.heritage.mainPage" %>
default.aspx.vb
Namespace heritage
Public Class mainPage : Inherits pageTemplate
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
End Sub
Private Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Init
InitializeComponent()
End Sub
Private Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
If Not Page.IsPostBack Then
title = "new title"
keywords = "1, 2, 3"
Description = "description try"
End If
form.Controls.Add((New LiteralControl("page content")))
End Sub
End Class
End Namespace
david7777
05-06-2003, 08:01 AM
Thanx a lot angiras :thumbsup:
So is using a page template the best way? I just dont want to go through the trouble of what seems to be quite a big job, and then realise there is a better way...
Forgive me, but I am still learning ASP.net, so i havent worked with classes yet... - Im not too sure on how this all works, but ill give it a try and get back to you if i have any problems... Thanx again!
david7777
05-06-2003, 08:21 AM
<%@ Page Codebehind="default.aspx.vb" Inherits="test.masterPage.heritage.mainPage" %>
Where does the text in bold red come from? why test.masterPage.heritage.mainPage?
I used the code you gave me, with the first part of code in template_page.vb. The second part in default.aspx and the 3rd in default.aspx.vb
I get the error - Could not load type 'test.masterPage.heritage.mainPage'.
Did i do something wrong?
angiras
05-06-2003, 08:29 AM
test.masterPage.heritage.mainPage
test.masterPage is my nameSpace Root
then I have a class with
Namespace heritage
and the class itself has name mainPage
for exemple you build an application =
then your root namespace will be david and your dll = david.dll
then you can create a group of pages under another (sub)namespace
namespace Admin
it will be then david.Admin
and any class under this namespace will be
class AnyClass
david.Admin.AnyClass
I hope it is clear enough :-((
it's a way to organize your application
angiras
05-06-2003, 08:31 AM
if you want to avoid inheritance you can try ascx file with all the content in it
david7777
05-06-2003, 08:36 AM
Oh ok! :D
That makes sense!
Do you know of any good sites i can check to learn how to use all that? Like dll's (how to create and compile) and namespaces and so forth...
It would be easier just to ask you how to create my namespace root, but thats not going to help me, is it? :confused:
Thanx alot for you help! :thumbsup:
david7777
05-06-2003, 08:39 AM
Posts crossed...
if you want to avoid inheritance you can try ascx file with all the content in it
no - i want to do this the propper way... I need to learn the hard stuff - it is there for a reason, and needs to be used :)
angiras
05-06-2003, 09:25 AM
you said : no - i want to do this the propper way
but microsoft itself use ascx as masterPage
I use it if I work with a designer, for myself I use inheritance
I have join here a Zip from microsft masterPages you can have a look
-------------------------
for dLL (how to create and compile) if you have visual studio it does it alone, otherwise you have a bat file into the zip which will compile it
david7777
05-06-2003, 10:50 AM
I appreciate that - thanx a lot! :thumbsup:
david7777
05-06-2003, 12:13 PM
I have tried to use the files you gave me in the zip, but it doesnt work... I have never run c# on my IIS, but im sure that shouldn't be a problem?
I get the error:
Parser Error Message: File or assembly name MasterPages, or one of its dependencies, was not found.
Source Error:
Line 1: <%@ language="c#" debug="true"%>
Line 2: <%@ Register TagPrefix="mp" namespace="Microsoft.Web.Samples.MasterPages" assembly="MasterPages" %>
Line 3:
Line 4: <script runat="server">
Source File: c:\inetpub\wwwroot\pagemaster\TestPage.aspx Line: 2
:confused: :confused: :confused:
Any suggestions?
PS - I did compile the dll with the bat file.
angiras
05-06-2003, 02:05 PM
ok let's say you have an application named test.masterPage (c:\inetpub\wwwroot\test.masterPage\)
you will get a dll as test.masterPage.dll
then into your web.config just put this 2 lignes into appSettings section
web.config
<appSettings>
<add key="masterPage.defaultFolder" value="modeles" />
<add key="masterPage.templateFile" value="template.ascx" />
</appSettings>
----------------------------------
into a folder named modeles
template.ascx
<?xml version="1.0" encoding="iso-8859-1"?>
<%@ Control CodeBehind="template.ascx.vb" Inherits="test.masterPage.masterPageMS.template" %>
<%@ Register TagPrefix="ms" namespace="test.masterPage.masterPageMS" assembly="test.masterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='fr'>
<head>
<title><ms:region runat="server" id="region0">Default titre ici</ms:region></title>
</head>
<body>
<form id="frm" method="post" runat="server">
<table border width="100%">
<tr align="middle">
<td colspan="2"><div id="header">This is the Header</div>
</td>
</tr>
<tr>
<td><h3>First arbitrary content area</h3>
<p>
<ms:region runat="server" id="region1">Default region1 content</ms:region></p>
</td>
<td><h3>Second arbitrary content area
</h3>
<p>
<ms:region runat="server" id="region2" /></p>
</td>
</tr>
<tr>
<td colspan="2"><h3>Third arbitrary content area
</h3>
<p>
<ms:region runat="server" id="region3">Default region3 content. It is displayed if the page does not define content for the region.</ms:region></p>
</td>
</tr>
<tr align="middle">
<td colspan="2"><div id="footer">This is the Footer</div>
</td>
</tr>
</table>
</form>
</body>
</html>
template.ascx.vb
Namespace masterPageMS
Public MustInherit Class template : Inherits UserControl
Protected WithEvents region0 As Region
Protected WithEvents region1 As Region
Protected WithEvents region2 As Region
Protected WithEvents region3 As Region
#Region " Web Form Designer Generated Code "
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
End Sub
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
End Class
End Namespace
---------------------------------------
at the root of your application :
default.aspx
<%@ Page Codebehind="default.aspx.vb" Inherits="test.masterPage.masterPageMS.mainPage" %>
<%@ Register TagPrefix="ms" namespace="test.masterPage.masterPageMS" assembly="test.masterPage" %>
<ms:contentContainer id="cc" runat="server" masterPageFile="">
<ms:content id="region0" runat="server" />
<ms:content id="region1" runat="server">
<a href="MasterPages.htm" runat="server">Relative link test</a><br />
<asp:textbox id="tb1" runat="server" />
<asp:button text="Capitalize" onclick="ClickedCapitalize" runat="server" />
<asp:literal id="capitalized" runat="server" />
</ms:content>
<ms:content id="region2" runat="server">
<asp:textbox id="tb2" runat="server" /><asp:button text="Say hello" onclick="SayHello" runat="server" />
Hello <asp:literal id="name" text="[name goes here]" runat="server" />!
</ms:content>
</ms:contentContainer>
default.aspx.vb
Namespace masterPageMS
Public Class mainPage : Inherits Page
#Region " Controles "
Protected WithEvents cc As contentContainer
Protected WithEvents region0 As Content
Protected WithEvents region1 As Content
Protected WithEvents region2 As Content
Protected WithEvents tb1 As System.Web.UI.WebControls.TextBox
Protected WithEvents Button1 As System.Web.UI.WebControls.Button
Protected WithEvents capitalized As System.Web.UI.WebControls.Literal
Protected WithEvents tb2 As System.Web.UI.WebControls.TextBox
Protected WithEvents Button2 As System.Web.UI.WebControls.Button
Protected WithEvents name As System.Web.UI.WebControls.Literal
#End Region
#Region " Web Form Designer "
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
End Sub
Private Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Init
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
region0.Controls.Add(New LiteralControl("mon nouveau titre"))
region1.Controls.Clear()
region1.Controls.Add(New LiteralControl("titre ici"))
End Sub
#Region " Methodes "
Sub ClickedCapitalize(ByVal o As Object, ByVal e As EventArgs)
capitalized.Text = Server.HtmlEncode(tb1.Text.ToUpper())
End Sub
Sub SayHello(ByVal o As Object, ByVal e As EventArgs)
name.Text = Server.HtmlEncode(tb2.Text)
End Sub
#End Region
End Class
End Namespace
------------------------
then your masterPage.vb
Namespace masterPageMS
Public Class contentContainer : Inherits PlaceHolder
Implements INamingContainer
#Region " variables "
Private _contents As New ArrayList()
#End Region
#Region " proprietes "
Public Property masterPageFile() As String
Get
Return CStr(ViewState("masterPageFile"))
End Get
Set(ByVal Value As String)
Dim f, s As String
f = "~/" + ConfigurationSettings.AppSettings("masterPage.defaultFolder") + "/"
If f = "" Then
f = "~/modeles/"
End If
If Value <> "" Then
s = Value
Else
s = ConfigurationSettings.AppSettings("masterPage.templateFile")
End If
ViewState("masterPageFile") = f + s
ChildControlsCreated = False
End Set
End Property
#End Region
#Region " constructeurs "
Sub New()
MyBase.new()
End Sub
Protected Overrides Sub AddParsedSubObject(ByVal obj As Object)
If TypeOf obj Is Content Then
_contents.Add(obj)
Else
Throw New Exception("le controle conteneur ne peut contenir que des controles")
End If
End Sub 'AddParsedSubObject
Protected Overrides Sub OnInit(ByVal e As EventArgs)
If masterPageFile Is Nothing Or masterPageFile = "" Then
Throw New Exception("Il faut definir les proprietes du masterPageFile")
End If
Dim masterPage As Control = Page.LoadControl(masterPageFile)
Dim content As content
For Each content In _contents
' Look for a region with the same ID as the content control
Dim [region] As Control = masterPage.FindControl(content.ID)
If [region] Is Nothing Then
Throw New Exception("region non trouvee pour l' ID '" + content.ID + "'")
End If
' Set the Content control's TemplateSourceDirectory to be the one from the
' page. Otherwise, it would end up using the one from the Master Pages user control, which would be incorrect.
content._templateSourceDirectory = TemplateSourceDirectory
' Clear out any default content that the region might have
[region].Controls.Clear()
' Move the content control into its designated region
[region].Controls.Add(content)
Next content
' Add the master page to the content container control
Controls.Add(masterPage)
MyBase.OnInit(e)
End Sub
#End Region
End Class 'contentContainer
'/ The control marks a place holder for content in a master page.
Public Class [Region] : Inherits PlaceHolder
Implements INamingContainer
End Class '[Region]
Public Class Content : Inherits PlaceHolder
friend _templateSourceDirectory As String
Public Overrides ReadOnly Property templateSourceDirectory() As String
Get
Return _templateSourceDirectory
End Get
End Property
End Class 'Content
End Namespace
-------------------------
you must just compile the dll including the 3 files
masterpage.vb
modeles/template.ascx.vb
default.aspx.vb
angiras
05-06-2003, 02:16 PM
vbc /t:library /r:System.Web.dll /r:System.dll /out:bin\test.masterPage.dll *.vb modeles\*.vb >> test.masterPage.txt
you copy paste this into a mp.bat file and run the compile
if you have an error you will get it written into the test.masterPage.txt
david7777
05-07-2003, 11:42 AM
Where would i import other namespaces like System.web.UI etc?
When i compile, i get some errors stating that
C:\Inetpub\wwwroot\test.masterPage\default.aspx.vb(3) : error BC30002: Type 'Page' is not defined.
Public Class mainPage : Inherits Page
I can fix that by adding in the namespace to every object used, but it would be a lot easier knowing where to just import each one once.
Something like:
import System.web.UI
import System.text
etc...
david7777
05-07-2003, 12:34 PM
Ok - After a few changes, I got it all working - Thanx a million!! :D :thumbsup:
angiras
05-07-2003, 01:15 PM
:-))
david7777
05-07-2003, 01:57 PM
Oh dear - i found a problem... :confused:
Ok - I have worked out how to use everything fine, except for one problem.
I have the code,
region0.Controls.Add(New System.Web.UI.LiteralControl(" : Site Name"))
in the default.aspx.vb file in the Page_Load sub.
So basically - if my title(region0) is set to "Home" in default.aspx, then it should display "Home : Site Name" when viewed with the browser. The problem is - it is displaying "Home : Site Name : Site Name".
If I use this code in default.aspx.vb instead:
region0.Controls.Clear()
region0.Controls.Add(New System.Web.UI.LiteralControl(" : Site Name"))
Then the title comes out as " : Site Name"
So - if i clear the region, then ": Site Name" is displayed once, but if i dont clear it, then it is displayed twice after my set title. How do i find the problem?
Even if i try:
region0.Controls.Add(New System.Web.UI.LiteralControl(" : Site"))
region0.Controls.Add(New System.Web.UI.LiteralControl(" Name"))
I still get "Home : Site Name : Site Name"
It seems that the Page_Load event is called twice or something??
This problem is not only with the title, but all regions. As long as there are controls in the region, and in Page_Load i try add without clearing first, the added controlls double up. Im sure it will do the same on your computer. Just try the code you gave me and change the default.aspx.vb Page_Load code to this:
region1.Controls.Add(New System.Web.UI.LiteralControl("this is more text in"))
region1.Controls.Add(New System.Web.UI.LiteralControl(" region one and will double up"))
That's all - just those two lines. After recompiling, you will see that the text will appear twice... Any ideas?
angiras
05-07-2003, 02:44 PM
in your default.aspx
<ms:content id="region0" runat="server" />
in your default.aspx.vb
Private Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
region0.Controls.Add(New LiteralControl("new title"))
End Sub
in your template.ascx
<ms:region runat="server" id="region0">Default title</ms:region>
david7777
05-07-2003, 03:15 PM
I dont think you understand what i want to do:
In default.aspx I have this code:
<ms:content id="region0" runat="server" >Home</ms:content>
That sets the title of the page to Home
Now in default.aspx.vb I have this:
title_region.Controls.Add(New System.Web.UI.LiteralControl(" : MySite Online"))
That should add onto the given title. So it should now be "Home : MySite Online"
In template.ascx i have:
<title><ms:region runat="server" id="title_region" />MySite Online</title>
So basically, i want ": MySite Online" added to the end of the title of the page - Just for uniformity of the site...
So a page titled "Contact Us" should in fact show the title "Contact Us : MySite Online" and the same with any others...
angiras
05-07-2003, 03:48 PM
the default content is set into your ascx file
then you can do 2 things to change it :
in default.aspx
or in default.aspx.vb
if you change any contentRegion into am ascx file it will erase the ascx file
bu what could be is a small function which will automaticly add "MySite Online" to the end of each title
david7777
05-07-2003, 04:00 PM
I though of the small function, but i figured it out...
I just had the following code:
'default.aspx:
<ms:content id="title_region" runat="server" >Home</ms:content>
'Nothing in the Page_Load event of default.aspx.vb
'template.ascx
<title><ms:region runat="server" id="title_region" /> : MySite Online</title>
I didnt realise that the default content of a region will be added to the end of any content inserted by the default.aspx page...
So the result is what i needed.
Once again - thanx a lot for all your help!:D :thumbsup: :D :thumbsup:
angiras
05-07-2003, 05:06 PM
and normally , it could be that asp net 2.0 (and future visual studio) implements directly this master Pages
then it is open on the future
if you want another good step in the direction of master pages
have a look at
wilsondotnet (http://wilsondotnet.com/Tips/Threads.aspx?Topic=3)
and
aspAlliance (http://www.aspalliance.com/PaulWilson/Articles/)
I have developped my own master pages from thsi articles
david7777
05-08-2003, 07:53 AM
Thanx angiras - some good articles there...
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.