A page can have only one server-side Form tag

T

Tom

Hi all,

I posted the same question one week ago in
http://communities.microsoft.com/newsgroups/previewFrame.as
p?
ICP=msdn&sLCID=us&sgroupURL=microsoft.public.dotnet.framewo
rk.aspnet&sMessageID=%253C7d8d01c3b4a1%2524412f7770%
(e-mail address removed)%253E

The problem has not fixed till now.

Here is a register.aspx page:

<%@ Page language="c#" Codebehind="register.aspx.cs"
AutoEventWireup="false" Inherits="web.register" %>
<%@ Register TagPrefix="house" TagName="register"
Src="_register.ascx" %>

<!-- #include virtual="./top.aspx" -->
<table align="center" width="800" border="0"
cellspacing="0" cellpadding="0">
<tr valign="top">
<td width="160">
<!-- #include virtual="./left.aspx" -->
</td>
<td width="640">
<form id="_register" method="post" runat="server">
<web:register ID="register1" runat="server" />
</form>
</td>
</tr>
<!-- #include virtual="./bottom.aspx" -->

In top and left.aspx pages and _register.ascx, there are
user controls which need form tag to submit data.

Each form tag has it's corresponding function.

But, in a register.aspx page, it only allows one server-
side Form tag.

How should I fix it?

Thanks for any sound advice.
 
K

Kaustav Neogy

Hi Tom,

include the <form runat="server"> tag at the top before
all controls and it should work.

HTH.

Kaustav Neogy.
 
E

Eric Veltman

Tom said:
<!-- #include virtual="./top.aspx" -->
<!-- #include virtual="./left.aspx" -->
<!-- #include virtual="./bottom.aspx" -->

In top and left.aspx pages and _register.ascx, there are
user controls which need form tag to submit data.
Each form tag has it's corresponding function.
But, in a register.aspx page, it only allows one server-
side Form tag.

I'm not Microsoft, but I think the possibility to use server
side includes with ASP.NET is only for backwards compatibility
and to provide a lightweight way for including some raw HTML.

If you're working the ASP.NET way, using the Web Forms
framework and such, then server side includes are not the
way anymore for modularization of the user interface.
Use UserControls instead.

In fact I think using server side includes to "include"
another ASP.NET page containing web controls is not even
going to work properly, because including it would mean
that you get f.i. multiple Page_Load definitions in the
"parent" page or, if you use code behinds, multiple code
behinds for the "parent" page. Which one will be used ?
I don't know.

To keep it short, ditch server side includes
and go for UserControls ;-)

Best regards,

Eric
 
J

Joe

I'd have to agree, usercontrols are much handier and more in line with the
OO nature of .Net but if you're not ready to climb that learning curve quite
yet removing the form tags from your includes and wrapping the entire
mainpage in a <form runat="server"></form> tag should work.

Joe
 
T

Tom

Hi all,

I had included <form runat="server" id="_register"
method="post">. But, may I ask what does at the top before
all controls mean?

In top.aspx, there is <form runat="server" id="_top"
method="post">

In left.aspx, there is <form runat="server" id="_left"
method="post">

In register.aspx, there is <form id="_register"
method="post" runat="server">

Each page has it's submit button.

When I click the submit button in top.aspx, it will pass
parameters to top.aspx.cs to handle it and will not affect
left and main's form.

If I use user control instead of server side include, it
is the same error - "A page can have only one server-side
Form tag". Or, it showed textbox must has form tag (but,
html, head, form tags cannot be placed in user control).

Basically, I just want to have the same set of top, left
and buttom aspx pages for all aspx pages. And, top, left,
main have their own form tags to submit to their
respective cs files to handle.

Any idea?
 
E

Eric Veltman

Hello Tom,
If I use user control instead of server side include, it
is the same error - "A page can have only one server-side
Form tag". Or, it showed textbox must has form tag (but,
html, head, form tags cannot be placed in user control).

With ASP.NET, you can only have 1 <form runat=server ...>
tag in the page and all it's included controls together.
Typically it's placed in the page, and all referenced controls
are between the <form runat="server" ...> start and end tag.
Unless you want to use just 1 user control on a page,
user controls must _not_ contain a <form runat="server" ...> tag.

Coming from old fashioned ASP, you may then wonder how on
earth to ensure that, when you click some button on the client,
the postback is handled by the right usercontrol.

Well, this is handled by the ASP.NET framework. All your
usercontrols are "naming containers", and as a result, in the
"name" attribute of all child controls of a user control,
the name of the parent user control is prepended. This way
ASP.NET knows which form input it should pass to which control
on postback.
Basically, I just want to have the same set of top, left
and buttom aspx pages for all aspx pages. And, top, left,
main have their own form tags to submit to their
respective cs files to handle.

As I said in another reply, using aspx pages ( that use the
web forms framework ) as server side includes is very doubtful
and I don't believe that's ever going to work properly.

Best regards,

Eric
 
T

Tom

Hi Eric,

I installed the IBuySpy demo from asp.net and it uses user
control for menu and header.

Just what I learnt from mircosoft tutorial
(http://msdn.microsoft.com/library/default.asp?
url=/library/en-
us/vbcon/html/vbconintroductiontowebusercontrols.asp), the
user control does not have <HTML>, <BODY>, and <FORM>
elements in it (these elements must be in the hosting
page).

But, there is a form tag (<form method="post"
action="SearchResults.aspx" id="frmSearch"
name="frmSearch">) in _Header.ascx of that demo.

So far as your reply:

Well, this is handled by the ASP.NET framework. All your
usercontrols are "naming containers", and as a result, in
the "name" attribute of all child controls of a user
control, the name of the parent user control is prepended.
This way ASP.NET knows which form input it should pass to
which control on postback.

Do you have any code example?

Anyone had built a website which has many pairs of
<form></form> tags in a single aspx page? Or, how to do
the naming containers?

Please advise.
 
T

Tom

Hi Eric,

I need your help again.

because ASP.NET prefixes the "name" property of all
controls in a user control by the name of the user control,
it can pass the right form input to the right control
on postback, so that control will generate an event
and the event handler defined in the user control's
code behind can handle it.

So if a button in a user control is clicked,
the event can be caught and handled in the
code behind of the user control.

That's what I do not know how to do it.

Here are my code:

A register.aspx includes 2 user controls.

register.aspx

<%@ Page language="c#" Codebehind="register.aspx.cs"
AutoEventWireup="false" Inherits="web.register" %>
<%@ Register TagPrefix="web" TagName="top" Src="_top.ascx"
%>
<%@ Register TagPrefix="web" TagName="left"
Src="_left.ascx" %>
<%@ Register TagPrefix="web" TagName="bottom"
Src="_bottom.ascx" %>
<%@ Register TagPrefix="web" TagName="register"
Src="_register.ascx" %>

<form runat="server" method="post" ID="Form13">
<web:top ID="top1" runat="server" />
<table align="center" width="780" border="0"
cellspacing="0" cellpadding="0">
<tr valign="top">
<td width="140">
<web:left ID="left1"
runat="server" />
</td>
<td width="640">
<web:register
ID="register1" runat="server" />
</td>
</tr>
<web:bottom ID="bottom1" runat="server" />
</form>

You can see that I put the form tag on a single aspx page
which includes several user controls and each of them has
a form to submit.

_left.ascx

<table width="100%" border="1" bordercolor="#9999e7"
cellspacing="0" cellpadding="2">
<tr bgcolor="#9999e7" align="middle">
<td>user register</td>
</tr>
<tr>
<td>
<table width="100%" border="0"
cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td
width="5">&nbsp;</td>
<td
nowrap>user name:</td>
<td>

<asp:TextBox id="username" runat="server"
CssClass="form" Width="70px"></asp:TextBox>

<asp:RequiredFieldValidator id="RequiredUserName"
runat="server" ErrorMessage="pls enter user name!"
Display="None" EnableViewState="False"
ControlToValidate="username"></asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td
width="5">&nbsp;</td>

<td>Password:</td>
<td>

<asp:TextBox id="PassWord" runat="server"
Width="70px" CssClass="form"
TextMode="Password"></asp:TextBox>

<asp:RequiredFieldValidator id="RequiredPassword"
runat="server" ErrorMessage="Pls enter password!"
Display="None" EnableViewState="False"
ControlToValidate="PassWord"></asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<td
width="5">&nbsp;</td>

<td><asp:button id="ibtnLogin" runat="server"
text="Submit"></asp:button>&nbsp;</td>
<td><a
href="lostpassword.aspx" target="_blank">Lost
password</a></td>
</tr>
<tr>
<td
width="5">&nbsp;</td>
<td
colspan="2"><asp:ValidationSummary id="ValidationSummary"
runat="server" ShowSummary="False" ShowMessageBox="True"
EnableViewState="False"></asp:ValidationSummary>

<asp:Label id="labErrorMSG" runat="server"
CssClass="node"></asp:Label>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</table>


_register.ascx

It also has a register form.

Here is the _register.ascx.cs

private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the
page here
if(!IsPostBack)
{
this.Bind_New();
}
}

Here is the _left.ascx.cs

private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the
page here
}

I am not sure how to write code for these 2 Page_Load and
PostBack.

Could you give me some hints?

Thanks a lot

Tom
 
E

Eric Veltman

Hello Tom,
I am not sure how to write code for these 2 Page_Load and
PostBack.

Could you give me some hints?

Pages and user controls have the same lifecycle,
i.e. the order in which events are emitted, which
is something like ...

Page_Init
I believe this one is called from the constructor.
If you need to do some very early initialization
for your control or page, do it here, but, if I remember
correctly, you don't have access to ViewState yet and
controls may have not been instantiated yet.

Page_Load
Normally, you can do initialization here.
You can determine whether it's a postback by checking
the Page.IsPostBack property. At this stage, controls
have already been created and ViewState has been used
to restore the state of the controls. For controls that
are dynamically created from Page_Load, ViewState is also
loaded into them just after Page_Load and before the
change events.

Change events
The events that controls emit when their value changes.
For instance applicable to textboxes and dropdowns.

Click events
The events that controls emit when they are clicked.

Page_PreRender
Just before rendering. ( Outputting HTML to client )

Page_UnLoad
You can do cleanup here.

The other hint I can give you is to think about the
responsibility of your controls, i.e. what is each control
supposed to do, which control does what ? And put the logic
in the user control in which it belongs.

So if you want something to happen when you click
a cmdLogin button in login.ascx, you put the handler
for the cmdLogin.Click event in login.ascx.cs.

If necessary, you can communicate from your page/control
with other controls by having controls emit events,
by exposing properties and methods.

Best regards,

Eric
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top