By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,806 Members | 1,089 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,806 IT Pros & Developers. It's quick & easy.

strange server-side validation postback

P: n/a
hi,
using .net 2.0, i have a web form with lots of textboxes, drop-down-lists
etc. There are lots of required field validators and regular expression
validators. When i click the 'save' button, the client-side validation is
executed immediately and the errors flash up on screen. However at the same
time, a post-back is performed and the page is obviously un-usable while it
is awaiting a response from the server. it looks very poor from a user
perspective because they see all the errors and have to wait a few seconds
for the page to re-load just to show the same errors. the average user
would not be aware that the page was re-loading and would attempt to ammend
the errors.

all the validators are set to Display=Dynamic and EnableClientScript=true.

this happens in up-level browsers Firefox 1.5.0.6 and Internet Explorer 6.
using the cassini/VS web server.

any clues why this would be happening?
thanks
tim
Aug 21 '06 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Hello Tim,

Long time no see and how are you doing?

Based on my description here, your ASP.NET 2.0 page will postback even if
there're client-side validation error occur, correct?

I think we need to identify which element or script function cause this
postback. You can start debugging on the web application and add some break
points in some postback event handlers and other page events to see whether
the strange postback will hit into any of the breakpoints. Also, in the IIS
log, you should be able to find the entries associated with this postback.

In addition, as you mentioned that the problem page is quite a
large/complex one(with lots of input entry fields ...), is it possible that
you reproduce the problem behavior through a simplifed test webform? If
so, we can help perform some tests on our local side.

Please feel free to let me know if there is anything I've missed.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead
This posting is provided "AS IS" with no warranties, and confers no rights.

Aug 22 '06 #2

P: n/a
hi Steven,
thanks for the reply. yes i've been tied up with development for a good
while! good to be back.

you're right, i did some further debugging and the button click event
handler was indeed firing. The reason is because i was using an extended
Button class i wrote, called "SmartButton", which you actually helped me out
with in september last year on this group. it uses javascript to manually
submit the form, having disabled itself and changed its text to "Please
wait...", in order to prevent duplicate clicks by the user, and to provide a
visual cue that the page is busy. the javascript code i was using doesn't
work with the new way .Net 2 submits a form, e.g.

onclick="javascript:WebForm_DoPostBackWithOptions( new
WebForm_PostBackOptions("btnSave", "", true,
"", "", false, false))

the full code for my 1.1 version is listed on my blog:
http://tinyurl.com/owh9y
the Render method is where the problem is, i tried this simple change in an
attempt to get it working with .net 2.0:
{
this.OnClientClick += ";this.disabled = true; this.value = 'Please
wait...';";
base.Render(output);
}

but it is too simplistic because the button remains disabled regardless of
client side validation. it needs to disable itself after successful client
validation and immediately before the form is actually submitted to the
server. i can't figure out how to do this because the function
WebForm_DoPostBackWithOptions is not listed on the page, i guess it's in
/WebResource.axd...

would you have any suggestion on how to achieve the same effect with .Net
2.0?

many thanks in advance
tim.
Aug 22 '06 #3

P: n/a
Thanks for your reply Tim,

Now I've got that the problem is actually due to the changing of the
ASP.NET button's postback mechanism.

As you have found, in ASP.NET 2.0 pages, the Button has exposed a
"OnClientClick" property to set client-side onclick script handler. And the
runtime emit a "WebForm_DoPostbackWithOptions" function to replace the
original "__doPostback" function in 1.0. Also, the built-in script is no
longer placed in a shared public folder but rendered out through a resource
handler(webresource.axd)...

Actually you can still manually request the resource content through the
generated url, such as:
<script
src="/ASPNET/V2/WebSites/NewTestSite/WebResource.axd?d=yDa86RJ5BlmQizOjOSj4H
M3nrNOaEBU0Q3mZezasA2o1&amp;t=632882923848905939"
type="text/javascript"></script>
You can pick the url out and directly access it in brower and get the
jscript content. I've performed some overview on the built-in scripts.
"WebForm_DoPostbackWithOptions" function will take a single parameter of
"Webform_PostBackOption" which contains several constructor params. The
first is the name of the element which trigger the postback. The last is a
boolean, indicate whether the function need to explicitly call form.submit
(for submit button, this is always false). e.g.

==============
WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("btnSubmit", "",
true, "", "", false, false));
==============

I've tested in my own button's "OnClientClick" and find that we can call it
manually in our client-script to trigger the page's client-side vailadtion,
and then check the "Page_Isvalid" global script variable to determine
whether the page has validation error. If there is no error, we let it go,
else wise, we stop our "smart button"'s client-side behavior.
I've created a test page to demonstrate the work, I've attached the page's
files in this message. You can get it if you're using outlook express to
access the newsgroup. If necessary, I can send you via email.
I'll also paste the page's aspx and codebehind here:
#btw, I use a hidden disabled button instead of disabling the real button
since this can avoid additional work to set POSTBACK arguments

===========aspx==================
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script id="btn_script" language="javascript">
function btn_click(btn)
{
WebForm_DoPostBackWithOptions(new
WebForm_PostBackOptions("btnSubmit", "", true, "", "", false, false));

if(!Page_IsValid)
{
return false;
}

btn.style.display = "none";
document.getElementById(btn.id + "Fake").style.display = "";

return true;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
runat="server" ControlToValidate="TextBox1"

ErrorMessage="RequiredFieldValidator"></asp:RequiredFieldValidator>


<asp:Button ID="btnSubmit" runat="server" Text="Normal Submit
Button" OnClick="btnSubmit_Click" />

<br />smart button <br />
<hr /><br />

<span>
<asp:Button ID="btnSmart" runat="server" Text="Smart Button"
OnClick="btnSmart_Click" OnClientClick="btn_click(this);" />
<asp:Button ID="btnSmartFake" runat="server" Text="Smart Button"
Enabled="false" style="display:none" />
</span>
</div>
</form>
</body>
</html>
==========code behind================
public partial class ControlPages_TestButtonPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}
protected void btnSubmit_Click(object sender, EventArgs e)
{
Response.Write("<br/>Normal button postback........");
}
protected void btnSmart_Click(object sender, EventArgs e)
{
Thread.Sleep(2000);

Response.Write("<br/>Smart button postback........");
}
}

=============================================
Hope this helps.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead

==================================================

Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscripti...ult.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscripti...t/default.aspx.

==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
Aug 23 '06 #4

P: n/a
hi Steven,
nice code! thanks for going to all that trouble to post the full working
code. I will be glad to integrate this into my web library.

many thanks
tim
--------------------------
blog: http://tim.mackey.ie

"Steven Cheng[MSFT]" <st*****@online.microsoft.comwrote in message
news:lp**************@TK2MSFTNGXA01.phx.gbl...
Thanks for your reply Tim,

Now I've got that the problem is actually due to the changing of the
ASP.NET button's postback mechanism.

As you have found, in ASP.NET 2.0 pages, the Button has exposed a
"OnClientClick" property to set client-side onclick script handler. And
the
runtime emit a "WebForm_DoPostbackWithOptions" function to replace the
original "__doPostback" function in 1.0. Also, the built-in script is no
longer placed in a shared public folder but rendered out through a
resource
handler(webresource.axd)...

Actually you can still manually request the resource content through the
generated url, such as:
<script
src="/ASPNET/V2/WebSites/NewTestSite/WebResource.axd?d=yDa86RJ5BlmQizOjOSj4H
M3nrNOaEBU0Q3mZezasA2o1&amp;t=632882923848905939"
type="text/javascript"></script>
You can pick the url out and directly access it in brower and get the
jscript content. I've performed some overview on the built-in scripts.
"WebForm_DoPostbackWithOptions" function will take a single parameter of
"Webform_PostBackOption" which contains several constructor params. The
first is the name of the element which trigger the postback. The last is a
boolean, indicate whether the function need to explicitly call form.submit
(for submit button, this is always false). e.g.

==============
WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("btnSubmit", "",
true, "", "", false, false));
==============

I've tested in my own button's "OnClientClick" and find that we can call
it
manually in our client-script to trigger the page's client-side
vailadtion,
and then check the "Page_Isvalid" global script variable to determine
whether the page has validation error. If there is no error, we let it go,
else wise, we stop our "smart button"'s client-side behavior.
I've created a test page to demonstrate the work, I've attached the page's
files in this message. You can get it if you're using outlook express to
access the newsgroup. If necessary, I can send you via email.
I'll also paste the page's aspx and codebehind here:
#btw, I use a hidden disabled button instead of disabling the real button
since this can avoid additional work to set POSTBACK arguments

===========aspx==================
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script id="btn_script" language="javascript">
function btn_click(btn)
{
WebForm_DoPostBackWithOptions(new
WebForm_PostBackOptions("btnSubmit", "", true, "", "", false, false));

if(!Page_IsValid)
{
return false;
}

btn.style.display = "none";
document.getElementById(btn.id + "Fake").style.display = "";

return true;
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="RequiredFieldValidator1"
runat="server" ControlToValidate="TextBox1"

ErrorMessage="RequiredFieldValidator"></asp:RequiredFieldValidator>


<asp:Button ID="btnSubmit" runat="server" Text="Normal Submit
Button" OnClick="btnSubmit_Click" />

<br />smart button <br />
<hr /><br />

<span>
<asp:Button ID="btnSmart" runat="server" Text="Smart Button"
OnClick="btnSmart_Click" OnClientClick="btn_click(this);" />
<asp:Button ID="btnSmartFake" runat="server" Text="Smart Button"
Enabled="false" style="display:none" />
</span>
</div>
</form>
</body>
</html>
==========code behind================
public partial class ControlPages_TestButtonPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{

}
protected void btnSubmit_Click(object sender, EventArgs e)
{
Response.Write("<br/>Normal button postback........");
}
protected void btnSmart_Click(object sender, EventArgs e)
{
Thread.Sleep(2000);

Response.Write("<br/>Smart button postback........");
}
}

=============================================
Hope this helps.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead

==================================================

Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscripti...ult.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscripti...t/default.aspx.

==================================================

This posting is provided "AS IS" with no warranties, and confers no
rights.

Aug 23 '06 #5

P: n/a
Hi Tim,

Glad that the code is of assistance. However, since we are hacking into the
internal script library of ASP.NET, such script code like
"WebForm_DoPostbackWithOptions" is not guaranteed to work among multiple
versions, this is what we need to take care.

BTW, you are welcome to post here when you've finished the library so that
other community members and also reference them :)

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead
This posting is provided "AS IS" with no warranties, and confers no rights.

Aug 24 '06 #6

P: n/a
hi Steven,
your approach got me thinking.... i tried to find an approach that wouldn't
dependant on the WebForm_DoPostbackWithOptions function. I also didn't
really like having a duplicate Fake button beside the real one, although i
can see how it does solve some problems.
what i came up is below, for anyone interested. comments/suggestions
welcome. Tested in IE6 (win) and FireFox 1.5.0.6, with multiple buttons on
forms, and tons of client-side validation. The previous version of this
control had a problem in Firefox, if the user clicked back then the control
stayed disabled, which was annoying, this isn't a problem with this new
version.
i don't think window.onbeforeunload is supported by Mac / Mozilla, but IE +
FireFox is good enough coverage for me.

/// <summary>
/// A button control that disables itself when clicked.
/// This is to prevent duplicate clicks by impatient or novice users.
/// It requires the button to be placed in a server form.
/// </summary>
[DefaultProperty("Text"), ToolboxData("<{0}:SmartButton runat=server />")]
public class SmartButton : Button
{

/// <summary>
/// Use the OnClientClick event to set the __EVENTTARGET value to the
button client ID.
/// Attach an event to the window.onbeforeunload, to disable the button, so
that it happens after
/// successful client validation.
/// </summary>
protected override void Render(HtmlTextWriter output)
{
this.OnClientClick +=
String.Format("document.getElementById('__EVENTTAR GET').value = '{0}';",
this.ClientID);

this.Page.ClientScript.RegisterStartupScript(typeo f(string),
"SmartButton", @"
<script language='javascript' type='text/javascript'>
function DisableButton()
{
try{
var target = document.getElementById('__EVENTTARGET').value;
document.getElementById(target).disabled = true;
}catch(e){}
}
window.onbeforeunload = DisableButton;
</script>
", false);

base.Render(output);
}
}

in case anyone is wondering why i had to set the __EVENTTARGET manually,
you'd be right in thinking that this should be done by the
WebForm_DoPostbackWithOptions function, but it seems not to do it in time
for the window.onbeforeunload event. i could have used any hidden field, or
javascript variable, but i thought why not use the EVENTTARGET since that it
is its purpose anyway.

if anyone wants to know how to reference a compiled control like this, the
easiest way in .Net 2.0 is to add this to your web.config:
<system.web>
<pages>
<controls>
<add tagPrefix="custom" namespace="NameSpaceOfControl"
assembly="AssemblyContainingControl" />

then in your aspx, just add a control like so: <custom:SmartButton etc
/>

cheers.
tim

--------------------------
blog: http://tim.mackey.ie
Aug 24 '06 #7

P: n/a
Thanks for the followup and sharing the update.

I think the new idea is good. Actually I also feel a bit hesitate on the
former solution since I am sure such function like
WebForm_DoPostbackWithOptions is changable and not quite recommend to
directly use in our custom code.

I have tried your new approach and works good as long as the browser
support the onbeforeunload event.

Cheers,

Steven Cheng

Microsoft MSDN Online Support Lead

This posting is provided "AS IS" with no warranties, and confers no rights.

Aug 24 '06 #8

This discussion thread is closed

Replies have been disabled for this discussion.