A page can have only one server-side Form tag

  • Thread starter Thread starter Tom
  • Start date Start date
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.
 
Hi Tom,

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

HTH.

Kaustav Neogy.
 
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
 
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
 
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?
 
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
 
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.
 
Supposed in a register.aspx page. If it contains 3 user
controls, for example,

1. a search textbox in top.ascx
2. login name and password textbox in left.ascx
3. registration form in register.ascx

Since it does not allow more than one form tag in an aspx
page, there is only one pair of form tag in that aspx page.

However, there are top.ascx.cs, left.ascx.cs and
register.ascx.cs to handle the c# code.

If there is only one pair of <form> tag, do top.ascx.cs,
left.ascx.cs and register.ascx.cs useless?

All c# code should work in register.aspx.cs as the form
tag is placed in register.aspx.

Then, what is the actual use for user control? It seems it
does not has much use? does it?

I would be very appreciate if someone could give me a
simple example to handle this case.

Regards

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

Yes, possible, but then it isn't a form that makes
use of the web forms framework and the form tag is
not runat="server".
Do you have any code example?

I don't have Windows on my machine at home and as
I'm jobless right now, I can't make a small example
at the office either :-( The code that I have from
my projects can't be posted because of intellectual
property issues, so I can't give you an example.
But the tutorial on www.asp.net has some examples
of how user controls handle the events for their
own child controls :

http://www.dotnetjunkies.com/quickstart/aspplus/doc/webpagelets.aspx
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?

All user controls are naming containers, you don't
have to do anything special to make ASP.NET pass
the form input to the right controls on postback.
If you clicked on a button that is a child control
of a user control, then ASP.NET will pass the form
input for the button to the button and the button
will generate a server side event, which is caught
and handled by the event handlers that are defined
in the user control's code behind.

Best regards,

Eric
 
Hello Tom,
However, there are top.ascx.cs, left.ascx.cs and
register.ascx.cs to handle the c# code.
If there is only one pair of <form> tag, do top.ascx.cs,
left.ascx.cs and register.ascx.cs useless?

No, 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.

See the 6th example in the next tutorial.
http://www.dotnetjunkies.com/quickstart/aspplus/doc/webpagelets.aspx

Best regards,

Eric
 
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
 
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
 
Back
Top