What is the life cycle of an ASP button? - asp.net

I'm having an issue with the cycle of a page reload and I can't figure it out. I have an ASP button the runs at the server but it has an associated client side click. The client side Javascript is running correctly and returning true to the button click so it is also running. The Javascript makes a modification to the query string on the URL and this is also working. However, in the C# code behind, the query string is not there. Somewhere, I'm missing something.
The HTML link:
<asp:Button ID="btnRunMOReport" class="button-dbg" runat="server"
Text="Run MO Report" OnClick="btnMO_Report_Click"
OnClientClick="return validateCheckBoxesMO()" />
The JavaScript portion:
function validateCheckBoxesMO() {
token='xyz';
let url1 = window.location.href;
if (url1.indexOf("?") > 0) {
url1 = url1.substring(0, url.indexOf("?"));
}
url1 += "?hiddenToken=" + token;
window.location.replace(url1);
return true;
}
The hiddenToken is now represented on the page (?hiddenToken=xyz).
The code behind:
protected void btnMO_Report_Click(object sender, EventArgs e)
{
MailMessage mailtest = new MailMessage();
mailtest.IsBodyHtml = true;
SmtpClient SmtpServertest = new SmtpClient(ConfigurationManager.AppSettings["smtp_server"]);
mailtest.To.Add("Whoever#test123.com");
mailtest.From = new MailAddress("Whoever#test123.com");
mailtest.Subject = Request.QueryString["hiddenToken"];
mailtest.Body = "Whatever";
}
The mail comes just fine but the subject is blank. Somehow, during the page reload cycle, the query string has not yet been set.
If there is a better way to pass data from the JavaScript to the code behind, I'm all ears.
I want to launch another page from the code behind but I need some data that is returned from the JS. The token is actually something I fetch, process the JSON and now I want to make that token available to the code behind for additional information to add to the new URL I am constructing. Probably TMI for this but it is what I am trying to do.
Thanks for your assistance.

Your script isn't working because the browser makes a POST request to submit the form (and __VIEWSTATE) using the action="" attribute of the <form> that WebForms adds to your page.
When your client-script sets window.location it isn't changing how the <form> will behave. You could use your script to append the new querystring value to the <form>'s action="" attribute and this may work, however it will likely fail if the application has request-validation enabled (in which case ASP.NET will reject a tampered form submission).
As you're using WebForms (and you shouldn't be using WebForms in 2021...) you shouldn't try to fight it unless you understand how it all works (I'm not trying to be condescending: it took me years to figure it all out and I've been using WebForms since 2004).
Instead, provide the value through an <asp:HiddenField>:
Change your .aspx markup to this:
<asp:Button runat="server" ID="btnRunMOReport" class="button-dbg"
Text="Run MO Report" OnClick="btnMO_Report_Click"
OnClientClick="return validateCheckBoxesMO()" />
<asp:HiddenField runat="server" ID="superSecretHiddenField" />
Change your client script to this:
function validateCheckBoxesMO() {
const hiddenFieldId = '<%= this.superSecretHiddenField.ClientID %>';
const hiddenField = document.getElementById( hiddenFieldId );
token='xyz';
hiddenField.value = token;
return true; // <-- This is wrong, btw. Instead use `Event.prototype.stopPropagation()` - but that requires the on-click function to be wired-up correctly and I don't remember the specifics other than that WebForms *doesn't* do things correctly (not out-of-spite, but because WebForms predates the standardisation of client-script events).
}
And your code-behind to this:
protected void btnMO_Report_Click(object sender, EventArgs e)
{
MailMessage mailtest = new MailMessage();
mailtest.IsBodyHtml = true;
SmtpClient SmtpServertest = new SmtpClient(ConfigurationManager.AppSettings["smtp_server"]);
mailtest.To.Add("Whoever#test123.com");
mailtest.From = new MailAddress("Whoever#test123.com");
mailtest.Subject = this.superSecretHiddenField.Value;
mailtest.Body = "Whatever";
}

As noted, a button post back will in general over-write the url that you change. Unless you actually do a navigation client side that is caused by the js, then it will not persist.
So, on the most simple level, just drop in a text box, or hidden field, and put the value you need/want into that hidden textbox or field.
So, client side? Markup?
You can use this:
<asp:Button ID="Button1" runat="server" Text="Delete"
OnClientClick="SetHidden();"/>
<asp:HiddenField ID="HiddenField1" runat="server" ClientIDMode="Static"/>
<br />
<script>
function SetHidden() {
hField = document.getElementById('HiddenField1');
hField.value = 'zoo';
return true;
}
</script>
So in above, we set our value in js to zoo, and of course we do return true. If we return false then the asp.net button code server side will not run - so we can control this, or even say pop up a confirm dialog and return true/false based on that to control if the server side code behind will run.
Server side, code behind? You can now use this:
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Debug.Print(HiddenField1.Value)
End Sub
So the above is easy, clean. You can also use a text box, and set the style="display:none", but a hidden field is just as well and easy.

Related

Asp button to open new page without submit

I have this aspx script for the button for pop-up:
<asp:Button ID="btnNewEntry" Text="Post Code Search" OnClick="btnNewEntry_Click" runat="Server" target="_blank"/>
and behind:
protected void btnNewEntry_Click(object sender, EventArgs e)
{
ClientScript.RegisterStartupScript(this.Page.GetType(), "", "window.open('../search/postcode_search/Default.aspx?code="+ p +"','Post Code Search','width=800,height=300,left=100,top=100,resizable=yes'); popup_handle.focus();", true);
}
But as the button is clicked the pop-up is opened but the parent page is refreshed. Why it's so? any work around?
Page got refreshed when a request to server is made, and server controls like Button has a property AutoPostback = true by default which means whenever they are clicked a trip to server will be made. Set AutoPostback = false for insert button, and this will do the trick for you.
or
Add OnClientClick="return false;" ,
<asp:button ID="btninsert" runat="server" text="Button" OnClientClick="return false;" />
Perhaps a little explanation of what is actually happening with your code will help. We have already discussed the auto postback, so you know that clicking that button will send the event back to the server. The page initializes again and reloads the view state and all of the posted data. After that, the button click event is handled.
At this point, your code writes the window.open script to the page. Keep in mind this is no where specific. This is just script that is added some where on the page and executed. The view state then gets updated and the page is sent back to the client. If the user reloads the page, that script is going to execute again.
Your best bet is going to be converting that to a client side button only. Find a way to get the necessary data back from the server before loading your popup. The easiest way to do that is make an AJAX call and open your pop up on success from your end point.
Try this.Updated one.
<asp:Button ID="btnNewEntry" Text="Post Code Search" OnClick="btnNewEntry_Click" runat="Server" target="_blank"
OnClientClick="javascript:window.open('../search/postcode_search/Default.aspx?code=+ p','Post Code Search','width=800,height=300,left=100,top=100,resizable=yes').focus();return false;"/>
Issue was due to "+ p +".
So as advised, i decided to go to client side. Here is my script:
<button onclick="OpenPopup()" type="button">Post Code Search</button>
and javascript code above it:
<script>
function OpenPopup() {
var getQueryString = function ( field, url ) {
var href = url ? url : window.location.href;
var reg = new RegExp( '[?&]' + field + '=([^&#]*)', 'i' );
var string = reg.exec(href);
return string ? string[1] : null;
};
var str = getQueryString('code');
if (str != null) {
p = str.replace(/%20/g, ' ');
}
else {
p = "";
}
var url = "../search/postcode_search/Default.aspx?code=" + p;
window.open(url, "Post Code Search", "toolbar=no, location=no,status=yes,menubar=no,scrollbars=yes,resizable=no, width=750,height=400,left=430,top=100");
return false;
}
</script>
so basically what it does, it grabs parameter from parent window url and adds to popup window url. My parent window url:
/Customer.aspx?code=V6E%20111&firstname=MyName
I hope it helps for others as well. Thanks for help guys.

Braintree Drop-In UI in ASP.NET web form with submit button method is not called when clicked

I have created a simple payment form where contains fields that accept amount, the drop-in UI and the submit button.
<form id="form1" runat="server">
<div>
<label>Amount:</label>
<asp:TextBox ID="txtAmount" runat="server" />
</div>
<div id="dropin-container"></div>
<asp:Button ID="btnSubmit" runat="server" OnClick="btnSubmit_Click" Text="Submit" />
<script src="https://js.braintreegateway.com/v2/braintree.js"></script>
<script>
braintree.setup("<%= this.ClientToken %>", "dropin", { container: "dropin-container" });
</script>
and the code behind
protected string ClientToken = String.Empty;
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
GenerateClientToken();
}
}
protected void GenerateClientToken()
{
var gateway = new BraintreeGateway
{
Environment = Braintree.Environment.SANDBOX,
MerchantId = "merchant-id",
PublicKey = "public-key",
PrivateKey = "private-key"
};
this.ClientToken = gateway.ClientToken.generate();
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
var gateway = new BraintreeGateway
{
Environment = Braintree.Environment.SANDBOX,
MerchantId = "merchant-id",
PublicKey = "public-key",
PrivateKey = "private-key"
};
var request = new TransactionRequest
{
Amount = Convert.ToDecimal(this.txtAmount.Text),
PaymentMethodNonce = Request.Form["payment_method_nonce"]
};
Result<Transaction> result = gateway.Transaction.Sale(request);
}
After I load the page in the browser, I can see the form that accept amount and also the drop-in ui form which accept credit card and/or PayPal.
The issue is when I click Submit button, the method btnSubmit_Click doesn't get called. The page looks like it post back correctly but I cannot see any line of code within the btnSubmit_Click is executed.
I follow the instruction from this page:
https://www.braintreepayments.com/features/drop-in
But I really can't think of anything that I miss.
Anyone can help me with this issue would be very appreciated. Thank you so much.
Knott
I work at Braintree and can help you with this question.
Some background on what braintree.js is doing when you load the Drop-in on your page: it listens for form submissions, and when it detects one it will interrupt the form submit, communicate with Braintree to generate a nonce, and then run your callback if defined. What’s happening is that your .NET postback event is broadcasting a submit action – the same type of action that braintree.js interrupts in the first place.
As a workaround, you can try adding the following to your Page_Load code:
ClientScript.GetPostBackEventReference(this, string.Empty);
ClientScript.RegisterClientScriptBlock(this.GetType(), "PayEvent","<script>function PayEvent() {document.getElementById('__EVENTTARGET').value = '"+ btnSubmit.ClientID +"'; }</script>" );
btnSubmit.Attributes.Add("onClick", "PayEvent()");
Where btnSubmit is the ID of your button.
This should circumvent the submit interruption and allow your form to be submitted properly. In addition, this problem does not occur with our custom integration as an alternative.
Let us know if you have any further questions.
You just needed to put your transaction request code in a method and then call that sub on a post back rather than page load.
This way the auto submit won't interrupt with things.
Protected void Page_Load(object sender, EventArgs e) {
if (!Page.IsPostBack) {
GetClientToken();
} else {
Pay();
}
}
protected void Pay() {
PaymentMethodNonce = Request.Form["payment_method_nonce"]
//Build request string etc.
}
Brian,
Your solution above was supplied to me by PayPal support, but unfortunately, it doesn't solve the problem.
To be honest, it is this 'listening' (read: unreliable, 'clever code') to form submissions which is causing all the problems when one tries to integrate it in a Web Forms/UpdatePanel page - it really isn't designed for WebForms/UpdatePanels and requires all kinds of really messy code to make it work and synchronise properly. It is almost as if it was never designed for anything other than MVC or Java!
What would be a far better solution would be if we could attach a JavaScript call in OnClientClick of a button which synchronously calls BrainTree/PayPal via a JavaScript module hosted on PayPal which returns the nonce so that we can then do something with it. As it stands now, the Braintree/PayPal code intercepts a submit button (all buttons in WebForms are 'submits' by default, so this causes problems) and fires off a call asynchronously to get a nonce and at the same time, calls the button OnClick in the C# code. The net result is that the C# code runs before the Braintree/PayPal call returns and you can never synchronise the two.

ASP.Net FormsAuthentication Rememberme

I am using forms authentication in a web application using the built-in Login capabilities, and it has been working well.
I would like to set DisplayRememberMe.visible to false depending on certain conditions (e.g. which Server, ip address, etc). Of course I can manually add visible="false" to the markup shown here, but that seems like a poor way to go.
<asp:CheckBox ID="RememberMe" runat="server" />
<asp:Label ID="RememberMeLabel" runat="server" AssociatedControlID="RememberMe"
CssClass="inline" >Keep me logged in</asp:Label>
Also, I can't figure out which asp field has the DisplayRememberMe field.
But more importantly, in the code behind file, I have added LoginUser.DisplayRememberMe = False, but it is ignored, and the label and checkbox are still visible. I have tried adding it to various events like Page.Load, Page.Init, Login_User.Init, Login_User.Prerender, but the checkbox and label are still visible after the page loads.
Am I using the proper call? Where should I place it to be effective?
This is my first post on SO, so please excuse any poor etiquette.
You can change visibility of CheckBox and Label by creating event of login control as
OnLoad="LoginUser_OnLoad"
On .cs page
protected void LoginUser_OnLoad(object sender, EventArgs eventArgs)
{
var login = (System.Web.UI.WebControls.Login)sender;
var checkbox = login.FindControl("RememberMe");
checkbox.Visible = false;
var label = login.FindControl("RememberMeLabel");
label.Visible = false;
}
You can also put your visibility conditions in LoginUser_OnLoad method.

ASP.NET: How do I navigate to a page after clicking a checkbox?

I have some checkboxes and a dropdownlist when the value changes I want to refresh the page while passing the new value. I tried using autopostback; however, the value is already in the url previously so when the postback occurs the value never changes.
Example:
CurrentPage: page.aspx?tab=Home&checkbox=True
Then I uncheck the checkbox so I want it to go to the following page...
IntendedPage: page.aspx?tab=Home&checkbox=False
But instead I the autopostback gives me this page...
DestinationPage: page.aspx?tab=Home&checkbox=True
Because, I handle the building of the url through a function on my page. Perhaps I'm doing something wrong by this point. If so I'd be happy to be corrected on my current setup. What I think I need to know though is how to load a custom URL on the checkbox.checkchanged event. I hope this made sense, if not let me know I'll try and clarify it. Thanks!
You could try something like this ( I have not tested, it was just an idea).
protected void CheckBox1_CheckedChanged ( object sender, EventArgs e )
{
string url = "page.aspx?tab=Home&checkbox="+ CheckBox1.Checked.ToString();
Response.Redirect ( url );
}
And then on the page:
<asp:CheckBox ID="CheckBox1" runat="server"
oncheckedchanged="CheckBox1_CheckedChanged" />
VB.NET Conversion
Protected Sub CheckBox1_CheckedChanged(sender As Object, e As System.EventArgs) Handles CheckBox1.CheckedChanged
Dim url = "page.aspx?tab=Home&checkbox=" & CheckBox1.Checked.ToString()
Response.Redirect(url)
End Sub
This is very easy to do through javascript. First add onclick="checkCheckBox(this);" to your checkbox.
<script language = "javascript" type="text/javascript">
function checkCheckBox(checkbox) {
if (checkbox.checked) {
window.location.href = '../page.aspx?tab=Home&checkbox=True';
}
else {
window.location.href = '../page.aspx?tab=Home&checkbox=False';
}
}
</script>
This should do it pretty easily.
This behavior is caused by the viewstate. The checkbox use it to persists its property, especially the checked property.
Actually, there is no out of the box link between a control and query string.
In your case, you will have two options, depending on your needs :
in the Checked event, build the expected url, and redirect the user to this page. The drawback is that you "loose" the viewstate and thus, the controls' state.
instead of using postbacks, use client side script (jQuery is your friend) to hide/show parts of the page. If the url matters, use # in the urls because it does allow staying on the same page.

Using of MessageBox class in Asp.Net

I am using MessageBox class in Asp.NET with C# by imposing the namespace
using System.Windows.Forms
I have the following code:
/* Method for displaying the Message Box */
public void MsgBox()
{
string message = "Do you want to modify the rate list?";
string caption = "";
MessageBoxButtons buttons = MessageBoxButtons.YesNoCancel;
DialogResult result;
result = MessageBox.Show(message, caption, buttons);
if (result == DialogResult.Yes) {
Response.Redirect("PaperRateList.aspx");
}
}
/*Calling of the above method in the following event */
protected void Save_Click(object sender, EventArgs e)
{
CompanyMaster_Insert();
RateList_Save();
MsgBox(); /*method*/
}
Now the problem is that the message box is appearing behind the form in minimized mode.and the form can be closed before closing the message bos.I want this messagebox on the form and i want to close the form after closing the message box.
MessageBox in web environment is not the best path to go, as it's a cheap way of implementing a windows form feature.
You have 2 ways to do this, server side (if you need to process some data) or client side (if you have all the data in the page and you can process it using javascript).
For you particulary example, you probably have a submit button like:
<asp:Button id="btnSave" runat="server"
onclick="btnSave_Click" text="Save Form" />
try to add this:
onclientclick="return confirm('Do you want to modify the rate list?');"
so it ends up like:
<asp:Button id="btnSave" runat="server"
onclick="btnSave_Click" text="Save Form"
onclientclick="return confirm('Do you want to modify the rate list?');" />
That's just using a javascript method called confirm.
To make nice MessageBox examples, and to avoid the user not to mess up with the page while the message is visible, it's called Modal Dialog or Modal Window, try to search for it...
jQuery UI has a Modal element that you can use, and if you fancy AJax stuff and you're a beginner in ASP.NET, I strongly suggest you to try the ASP.NET Control Toolkit
try
WebMsgBox class represents a message box for ASP.NET applications. This class has a static method Show, which is used to display a message box. The Show method takes a single argument of string type, which is the message you want to display.
private void Page_Load( object sender, System.EventArgs e )
{
MessageBox.Show( "Hello World!" );
MessageBox.Show( "This is my second message." );
MessageBox.Show( "Alerts couldnt be simpler." );
}
You can use ModalPopupExtender of AJAXControlToolkit:
ModalPopup Example

Resources