Custom Validator validates, but doesn't tell

R

Radu

Hi. I have an ASP control on my page:

<asp:Calendar
ID="calStart"
................ Etc
</asp:Calendar>

and I have a Custom Validator defined as

<asp:CustomValidator
id="validDate"
Text="*"
ErrorMessage= "The date of the meeting should be at least 7 business
days later than the day of the request !"
Display="Dynamic"
OnServerValidate="ServerValidate" runat="server">
</asp:CustomValidator>

and ServerValidate is defined as:

Protected Sub ServerValidate(ByVal source As Object, ByVal args As
System.Web.UI.WebControls.ServerValidateEventArgs)

Dim objCustomValidator As CustomValidator
Dim objValidationSummary As ValidationSummary
Dim dtChosenDate As Date

objCustomValidator = CType(source, CustomValidator)
objValidationSummary = CType(Me.FindControl("validSummary"),
ValidationSummary)
dtChosenDate =
CType(objCustomValidator.Parent.FindControl("calStart"),
Calendar).SelectedDate

'The date must be greater than today by 7 business days:
If DateDiff(DateInterval.Day, Now, dtChosenDate) < 9 Then
args.IsValid = False
objCustomValidator.IsValid = False
Else
args.IsValid = True
End If

objValidationSummary.Controls.Add(objCustomValidator)

objValidationSummary = Nothing
objCustomValidator = Nothing
End Sub

I also have a ValidationSummary control:
<asp:ValidationSummary
ID="validSummary"
CssClass="MyTextBox"
ShowSummary="false"
ShowMessageBox="true"
DisplayMode="BulletList"
HeaderText="The following data is wrong or missing:"
runat="server"
/>

The validation control works fine with all the others validators on
this page, except this CustomValidator: when I try to leave the page,
if the date is not greater than today by 9, it won't allow me to leave
the page (meaning it's working), but it does not register with the
ValidationSummary control. Where is my problem ?

On a side note - two more questions:
1. When I reset the page (after navigating back and forth), I say in
Page_Load
calStart.SelectedDate = ..... (valid date)
but nothing shows on the screen !
2. can I stop the calendar control from posting back ? Do I have to
write my own javascript-based calendar ?

Thank you very much.
Alex. Nitulescu
 
S

Scott M.

Wow! I think you have made this way more difficult than it needs to be.

- First, why aren't you doing this validation on the client (and then as a
backup measure on the server)?

- Second, why are you making new instances of controls that you already have
and can access on the server simply by using their id?

- Third, why are you accessing existing controls (and then casting them back
to their own type) via some other control, rather than directly?

- Fourth, why doesn't your code have a "Handles" clause on the event handler
declaration line (in other words, why do you have AutoEventWireUp set to
true)?

- Fifth, why are you setting your object references to Nothing? That's so
VB 6.0 and not necessary in VB.NET.

- Sixth, since calendar controls can't be validated, why not just put a
label on the page somewhere with an appropriate error message in it, but
make it hidden?

Here's how I think your server code should read (but I still think you
should add client-side validation as well to reduce server trips). This
code assumes you have placed a label control somewhere on your page and
called it "lblCalendarMessage". In addition, this label should have its
visible property set to False by default:

Protected Sub ServerValidate(ByVal source As Object, ByVal args As
System.Web.UI.WebControls.ServerValidateEventArgs)

'The date must be greater than today by 7 business days:
If calStart.selectedDate < Today.AddDays(9) Then
args.IsValid = False
lblCalendarMessage.visible = True
Else
args.IsValid = True
lblCalendarMessage.visible = False
End If
End Sub
On a side note - two more questions:
1. When I reset the page (after navigating back and forth), I say in
Page_Load
calStart.SelectedDate = ..... (valid date)
but nothing shows on the screen !

Are you putting this code inside of a Not IsPostBack check?
2. can I stop the calendar control from posting back ? Do I have to
write my own javascript-based calendar ?

All web form controls are server controls and, as such, they postback. If
you don't want this, then yes, you must come up with your own client side
calendar.
 
R

Radu

Scott, thank you very much for your answer.

1. You're right, I don't need the extra objects.
2. All the other objects on this page register with the
ValidationSummary, so if I show that label, this would be an exception
to the "rule of the page", and will be annoying.
3. I could do it on the client, and I should, I know, but I don't know
enough JScript to make it work. I could find the
calendar object, but then I could not finish the rest of the function
properly - I know I need to compare the dates in JavaScript and then
set args.IsValid to false. I will try to do that. OTOH, I think that I
need to write this function to make the validation summary work - it
might be that it does not show THIS message simply because my
CustomValidator control only has a server function, not a client one
as well.... I'm not sure of this, though.
4. I have AutoEventWireup="false", but I also have
OnServerValidate="ServerValidate" for the CustomValidator object, so I
think that Handles will not help in any way.
5. For the suppl. question #1 - yes, and the code passes thru there -
no errors, but it simply doesn't change anything - the calendar looks
the same, that date is NOT selected - the user has to select it again,
although all the other (many) controls on this page have retrieved
their values when the user navigates back and forth thru the pages of
the site (my web-site works as a 'Wizard', i.e. Step 1/9, Next, Step
2/9, Next, Step 3/9, etc, and Step 9/9=Commit, the last one. Until
here, all settings made in pages 1....8 can still be changed. This
page, with the calendar, is Step 8/9).

Thanks again, Scott, for reading this.
Alex.
 
S

Scott M.

See my comments inline:


Radu said:
Scott, thank you very much for your answer.

1. You're right, I don't need the extra objects.
2. All the other objects on this page register with the
ValidationSummary, so if I show that label, this would be an exception
to the "rule of the page", and will be annoying.

I don't know what "rule of the page" you are referring to. You already have
an exception, in that Calendar controls can't be validated directly, so the
label idea is the simplest solution. Just put the label next to your
validation summary and format the text the same way the validation summary's
text is formatted - problem solved.
3. I could do it on the client, and I should, I know, but I don't know
enough JScript to make it work. I could find the
calendar object, but then I could not finish the rest of the function
properly - I know I need to compare the dates in JavaScript and then
set args.IsValid to false. I will try to do that. OTOH, I think that I
need to write this function to make the validation summary work - it
might be that it does not show THIS message simply because my
CustomValidator control only has a server function, not a client one
as well.... I'm not sure of this, though.
4. I have AutoEventWireup="false", but I also have
OnServerValidate="ServerValidate" for the CustomValidator object, so I
think that Handles will not help in any way.

OnServerValidate has nothing to do with AutoEventWireUp. AutoEventWireUp
being false (which is what you have and what you should have) means that
event handlers (your Sub ServerValidate) will be called based on the
"Handles" clause on the event handler declaration. You don't have one, so
how and why would this Sub ever get called? AutoEventWireUp being set to
True (which is not the way you should set it) means that event handlers are
automatically called based on the name of the procedure (as in the old VB
6.0 world). In the old days event handlers had to be a combination of the
control name, an underscore and the event to handle (Button1_Click()). The
bottom line here is that you have AutoEventWireUp set correctly, but you
don't have a Handles clause. How did you create this event handler? Did
you type it in yourself or did you double-click on the validation control
and let VS .NET create the server-side event handler declaration for you
(the best way)?
5. For the suppl. question #1 - yes, and the code passes thru there -
no errors, but it simply doesn't change anything - the calendar looks
the same, that date is NOT selected - the user has to select it again,
although all the other (many) controls on this page have retrieved
their values when the user navigates back and forth thru the pages of
the site (my web-site works as a 'Wizard', i.e. Step 1/9, Next, Step
2/9, Next, Step 3/9, etc, and Step 9/9=Commit, the last one. Until
here, all settings made in pages 1....8 can still be changed. This
page, with the calendar, is Step 8/9).

This may have to do with ViewState and/or not placing your code inside of an
If Not IsPostBack Then statement inside of Page_Load.
 
B

bruce barker

not sure what you are trying to do. a validator has two properties,

Text = dynamic message to display when validation fails
ErrorText - message to display in summary when validation fails

not sure why you are adding your control to the summary, why you are not
using ControlToValidate.

-- bruce (sqlwork.com)
 
S

Scott M.

Inline....

bruce barker said:
not sure what you are trying to do. a validator has two properties,

Text = dynamic message to display when validation fails
ErrorText - message to display in summary when validation fails

not sure why you are adding your control to the summary, why you are not
using ControlToValidate.

Because Calendar controls can't be validated. If you try to set the
ControlToValidate property of a validator to a calendar control, you will
get a compilie error.
 
R

Radu

Scott, my comments are inline. Thanks.
I don't know what "rule of the page" you are referring to. You already have
an exception, in that Calendar controls can't be validated directly, so the
label idea is the simplest solution. Just put the label next to your
validation summary and format the text the same way the validation summary's
text is formatted - problem solved.

The "rule of the page" (and of the web-site, I might add) being that
all problems with the data are shown in a message-box, and therefore
this calendar control would be the only one which would show its error
text in a label. So you'll have (maybe at the same time) a label on
the side of the calendar saying "The value selected has to be....",
and a message box saying "Data....xxx... has to be numeric".
OnServerValidate has nothing to do with AutoEventWireUp. AutoEventWireUp
being false (which is what you have and what you should have) means that
event handlers (your Sub ServerValidate) will be called based on the
"Handles" clause on the event handler declaration. You don't have one, so
how and why would this Sub ever get called? AutoEventWireUp being set to
True (which is not the way you should set it) means that event handlers are
automatically called based on the name of the procedure (as in the old VB
6.0 world). In the old days event handlers had to be a combination of the
control name, an underscore and the event to handle (Button1_Click()). The
bottom line here is that you have AutoEventWireUp set correctly, but you
don't have a Handles clause. How did you create this event handler? Did
you type it in yourself or did you double-click on the validation control
and let VS .NET create the server-side event handler declaration for you
(the best way)?

How did I create it ? I simply started a new function, with its name
as specified in "OnServerValidate". Yes, you'll add, then why does it
execute without the Handles clause ? And still, it executes just the
same - I guess that mentioning its name in OnServerValidate is enough.
The code *PASSES* through there, guaranteed :))))
This may have to do with ViewState and/or not placing your code inside of an
If Not IsPostBack Then statement inside of Page_Load.

Yet..... the code passes through there - all my other controls are
properly re-initiated. I took it step-by-step, and the instruction
executes, but nothing happens :-(((

Thank you for answering.
Alex.
 
S

Scott M.

A couple of last thoughts, inline...


Radu said:
Scott, my comments are inline. Thanks.


The "rule of the page" (and of the web-site, I might add) being that
all problems with the data are shown in a message-box, and therefore
this calendar control would be the only one which would show its error
text in a label. So you'll have (maybe at the same time) a label on
the side of the calendar saying "The value selected has to be....",
and a message box saying "Data....xxx... has to be numeric".

Ok, no problem, don't use a label. Instead simply pass some client-side
JavaScript to the client from the server and have that script make an alert
with your error message, as in:

response.write("<SCRIPT TYPE='text/JavaScript'>alert('You must pick a date
at least 5 business days in the future.')</SCRIPT>")

My point is that this problem is more easily solved without trying to tap
into the validatorsummary control and making your server-side code much more
compicated.

How did I create it ? I simply started a new function, with its name
as specified in "OnServerValidate". Yes, you'll add, then why does it
execute without the Handles clause ? And still, it executes just the
same - I guess that mentioning its name in OnServerValidate is enough.
The code *PASSES* through there, guaranteed :))))

If you are using VS .NET, you should NEVER create the "shell" of an event
handler manually - this is a leading cause of errors. Instead, just
double-click on the control you wish to write server-side code for and let
VS.NET create the event handler for you. Even though you state that this
code is being called, I strongly reccomend you do this and copy the "guts"
of your existing procedure into the new one created by VS .NET and then
delete the empty old one.
Yet..... the code passes through there - all my other controls are
properly re-initiated. I took it step-by-step, and the instruction
executes, but nothing happens :-(((

But (for the third time), do you have your code written inside of a If Not
IsPostBack Then statement? The fact that the code passes through Page_Load
doesn't mean much (all pages process this event), but you only want the date
to change on a PostBack, right?
 
R

Radu

Wow, Scott, great idea, I put

Response.Write("<SCRIPT TYPE='text/JavaScript'>alert('A minimum of 7
business days from the request date is required in order to process
your demand.\nPlease pick a date at least 7 business days in the
future.')</SCRIPT>")

it in and, voila, it works. It's not acting exactly like the other
controls on the page, but at least it works !

Thanks a lot :)
Alex

PS. Yes, sorry, it *was* inside a "If Not Page.IsPostBack Then" block.
 

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

Forum statistics

Threads
474,039
Messages
2,570,375
Members
47,021
Latest member
AleciaMcMa

Latest Threads

Top