How to programmatically fail Page validation in button click? - c#

In my button click, I would like to cause the page validation to fail if it meets a certain criteria. The problem is that that Page.IsValid is read-only.
This is what I am trying in my button click:
protected override void CreateChildControls()
{
base.CreateChildControls(container);
MyBtn += MyBtn_Click;
MyBtn += MyBtn_Click2; // Cannot move this
}
protected void MyBtn_Click(object sender, System.EventArgs e)
{
CaptchaControl.Validate();
if (!CaptchaControl.IsValid)
{
Page.IsValid = false; // Error because read-only
// Stop before running MyBtn_Click2!
}
}
If my captcha fails validation, I want to return to the page immediately, before it starts running the 2nd click event. Any ideas on how to do this?

I would personally use a hidden field and mark it as required. Put a default value in it, and if your captcha fails, remove the value and revalidate the page.
if (!CaptchaControl.IsValid)
{
myHiddenField.Value = null;
Page.Validate();
}
If your myBtn2 control is using if (Page.IsValid) to execute code, the hidden required field should be empty and now invalid.

Related

ASP.NET validator one behind with code generated form

I have created server created forms using Telerik AJAX controls with a submit button that does a post (no click event). My forms use validators which work fine except they happen on the next post after the field validation error.
If I make an email field empty which the code logic catches and returns an error. Submit again and the email required field validator works to catch the error before the code. Now put valid data and submit and the last empty field validator error with appears again. Submit the good data a second time and it updates.
Also, if I produce my own validator error then the validators work fine. I have validator code for required checkboxes. If a missing check happens I call
ValidatorError.Display(Page, message);
which causes the subsequent
Page.Validate(FormEntryBase.VALIDATION_GROUP);
to properly validate required fields in current submit.
protected void Page_Load(object sender, EventArgs e) {
localValidationError = theForm.CustomValidateForm(Request.Form);
if (localValidationError) {
validateErrorList = form.validateErrorList;
// get local valiation error put into validation summary error list
if (validateErrorList != null) {
foreach (string message in validateErrorList) {
ValidatorError.Display(Page, message);
}
}
}
Page.Validate(FormEntryBase.VALIDATION_GROUP);
if (!Page.IsValid ) {
return;
}
Validator errors the code does not catch are not caught on an initial submit which lets bad data in.
I have another web form that uses the click method and only uses Page.IsValid which works fine.
Very strange behaviour, some sort life cycle problem probably.
With some luck, I figured out a solution by adding a click event in code. To add a click event, first I added the RadButton to my form creation code be accessed in the aspx.cs.
RadButton button = new RadButton();
button.ValidateRequestMode = ValidateRequestMode.Enabled;
button.ValidationGroup = VALIDATION_GROUP;
button.UseSubmitBehavior = true;
theForm.updateButton = button;
In the aspx.cs Page_Load I added the click method to the button.
protected void Page_Load(object sender, EventArgs e) {
...
theForm = group.GetJoinForm();
theForm.updateButton.Click += new EventHandler(UpdateButton_Click);
...
void UpdateButton_Click(object sender, EventArgs e) {
Page.Validate(FormEntryBase.VALIDATION_GROUP);
if (!Page.IsValid) {
return;
}
... most of page load code moved here
These three steps fixed my validate delay problems and all my forms now validate quite well.

bindingNavigator _Validating event not returning control to the form

I am trying to follow the MSDN example code for the Control.Validating Event and to apply it to a bindingNavigator item instead of the textbox as in the example.
The code provided for the textbox validation event is shown below.
private void textBox1_Validating(object sender,
System.ComponentModel.CancelEventArgs e)
{
string errorMsg;
if(!ValidEmailAddress(textBox1.Text, out errorMsg))
{
// Cancel the event and select the text to be corrected by the user.
e.Cancel = true;
textBox1.Select(0, textBox1.Text.Length);
// Set the ErrorProvider error with the text to display.
this.errorProvider1.SetError(textBox1, errorMsg);
}
}
I too intend on validating texboxes however I have several and have already written the validation methods for them which handle the error messages. I would like these methods to be tested when the user selects an item (Arrow buttons / Save button / Add button) on the bindingNavidator.
I therefore have the code below to attempt this,
private void myBindingNavigator_Validating(object sender, CancelEventArgs e)
{
if (!IsPostCodeValid())
{
PostCodeTextBox.Focus();
e.Cancel = true;
}
}
I have the ItemClicked event for the bindingNavigator set to bindingNavigator.Focus() with the hope of initiating the Validating event. (myBindingNavigator.CausesValidation = true; has been declared on formLoad). However I feel this is where an infinite loop of focusing the Navigation bar follows? I have stepped through and no code is executed once it has locked on to the Navigation bar it simply won't let the user interact with the rest of the form to change and correct the error after the navigation bar has been locked onto.
I can provide any extra information required and test any suggestions to discover what is going on.
Thanks
When you work with BindingNavigator and you have put your controls in details mode on the form, to ensure save only valid data, you should write validation rules for your controls and also you should handle your binding navigator items yourself.
This way you even don't need to set AutoValidate Property of your form to annoying EnablePreventFocusChange and you can set it to be the friendly EnableAllowFocusChange and because you can't navigate or save anything when there is validation errors, then you can be sure only valid data will save in database.
To do so, follow these steps:
Step 1
Handle Validating event of child controls and set e.cancel = true when the value is not valid.
private void nameTextBox_Validating(object sender, CancelEventArgs e)
{
//Put validation logic here
if (this.nameTextBox.Text.Length < 10)
{
e.Cancel = true;
this.errorProvider1.SetError(this.nameTextBox, "Some Error");
}
else
{
this.errorProvider1.SetError(this.nameTextBox, "");
}
}
Step 2
Go to BindingNavigator properties, and set MoveFirstItem, MovePreviousItem, MoveNextItem, MoveLastItem, AddNewItem, DeleteItem properties To (none). Also from designer click on the text box that shows record number, it is bindingNavigatorPositionItem, and then set its ReadOnly property to true.
Step 3
For all buttons, including navigation buttons, add button, delete button, save button and other custom buttons, handle Click event and call ValidateChildren method of the container of your text boxes and check if ValidateChildren() doesn't return true, exit the method, else do the task that the method should do, for example:
private void toolStripButton1_Click(object sender, EventArgs e)
{
if (!this.ValidateChildren())
return;
//Put the logic for this button here
//MoveFirstItem: `this.myBindingSource.MoveFirst();`
//MovePreviousItem: `this.myBindingSource.MovePrevious();`
//MoveNextItem: `this.myBindingSource.MoveNext();`
//MoveLastItem: `this.myBindingSource.MoveLast();`
//AddNewItem: `this.myBindingSource.AddNew();`
//DeleteItem: `this.myBindingSource.RemoveCurrent();`
}

Client Interaction in WebForms

What way is standard/ recommended to do the following:
When a user raises the Page_Command "Save" or "Send," I want to run a method. If the method returns false, I want to send the user back to the page and display a message.
All of the data they entered in the form should still be there. The message would have a button that reads, "Send Anyway/ Regardless." If they click it, it will send.
I know I could do this via a webservice and jQuery, but I am asking how I would do this via WebForms.
Here is my basic code:
protected void Page_Command(Object sender, CommandEventArgs e)
{
if ( e.CommandName == "Save" || e.CommandName == "Send" )
{
// run method
}
}
There are several ways you could do this.
One option might be to a button with the text "Save", and another with the text "Send anyway". Make the second button invisible to begin with, and the first visible.
When the first button is clicked, it should run the validation-logic. If validation succeeds, submit - otherwise, hide the first button, and set the other one to visible.
When / if the second button is clicked, the submit is performed without validation.
Update:
With some minor modifications, you should be able to do something like this:
Markup:
<asp:Button runat="server"
ID="myFirstButton"
OnClick="SubmitWithValidation" />
<asp:Button runat="server"
ID="mySecondButton"
Visible="False"
OnClick="SubmitData" />
Code:
protected void SubmitWithValidation(object sender, EventArgs e)
{
if (ValidateMyData())
{
SubmitData(sender, e);
}
else
{
mySecondButton.Visible = true;
myFirstButton.Visible = false;
}
}
private bool ValidateMyData()
{
// Validate stuff
return isValid;
}
private void SubmitData(object sender, EventArgs eventArgs)
{
// Logic to submit your data here
}

Silverlight callback mystery behavior

I am writting this method to track if changes occured on a page so the user can trigger a reload of a dependent system. So this as you can see triggers when the user is trying to navigate away from the page. If the e.Cancel is not there the behavior seems fine the async web-service call happen as expected but I am not sure what is really happening in the back.
The reload button click method triggers a chain of event that usually update the display but since the user has navigated away from the page the components are no longer visible. Can this cause problems to the application? Should I be forcing the user to remain on the same page just to prevent possible callback problems?
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
{
base.OnNavigatingFrom(e);
if (hasDataBeenModified)
{
if (System.Windows.Browser.HtmlPage.Window.Confirm("You have not reloaded the policies\nDo you want to do it now?"))
{
//e.Cancel = true;
ReloadButton_Click(null, null);
}
}
}
Instead of using OnNavigatingFrom, use OnBackKeyPress
protected override void OnBackKeyPress(CancelEventArgs e)
{
if (hasDataBeenModified)
{
if (System.Windows.Browser.HtmlPage.Window.Confirm("You have not reloaded the policies\nDo you want to do it now?"))
{
e.Cancel = true;
ReloadButton_Click(null, null);
}
}
}

ASP.net page_load doesn't detect session

I have a problem with using session variable in the page_load. I have a page (members.aspx) which is a members area.
If the user isn't logged in, it will display a form asking them to login. The form submits their details, checks if ok then sets session variables if OK. It then reloads the page.
So if the user has authenticated correctly, it sets Session["memberLoggedIn"] = true.
My page_load function then looks like this
protected void Page_Load(object sender, EventArgs e)
{
if (Convert.ToBoolean(Session["memberLoggedIn"]) == true) {
Response.Write("OK");
}
}
There is more code, but essentially, the "OK" should be written. However, it doesn't appear. Even though the session IS set. If I go to the page directly it will then show. It's just for the reloading of the members page from the initial login which stops it.
any ideas?!
======================
the code to set the session is
if (logindetails.Count > 0) {
System.Data.DataRow details = logindetails[0];
Session["memberLoggedIn"] = true;
}
I then just check if (Convert.ToBoolean(Session["memberLoggedIn"]) == true) on all my pages. To be honest it doesn't seem that reliable and I Think sometimes I need to understand the order in which pages are loaded as when I destroy the session on the log out page, some parts still show the logged in features! (but that's another story....)
try this
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostBack)
{
var user = HttpContext.Current.User;
if(user.Identity.IsAuthenticated)
{
Session["memberLoggedIn"] = true;
Print();
}
}
}
public void Print()
{
if (Convert.ToBoolean(Session["memberLoggedIn"]) == true)
{
Response.Write("ok");
}
}
This sounds like when you log in you are choosing whether to write "OK" before you have processed the login. In terms of the page's pipeline page_load is before your event handler that you are likely processing the login.
You have various options, the simplest of which could be to move this particular logic to Page_PreRender (if it makes sense to) as at this point your session variable will have been set.

Categories

Resources