I have a custom error handler for an asp.net site.
void Application_Error(object sender, EventArgs e)
{
// Code that runs when an unhandled error occurs
//if (System.Configuration.ConfigurationManager.AppSettings["ProductionMode"] == "Yes")
#if (!DEBUG)
Server.Transfer("~\\GlobalExceptionHandler.aspx");
#endif
}
It works fine and dandy when retrieving exception information cause it'll just snag Server.getLastException() and email it on to me for review
However, I have some TextBoxes on the page and I'd like to send the value of those textboxes along with the email. Maybe it's not quite the DOM I'm looking for access to but instead those posted variables.
I tried looking at HttpContext.Current.Request.Form but it showed no keys.
So Does anyone know how to access the formvalues when globally catching an exception?
Accessing the Form Values
To access the form values in Global.Application_Error, you can simply use HttpContext.Current.Request.Form.
Here is a proof of concept, where a page immediately throws an exception on post(back) to hit the application error handler:
void Application_Error(object sender, EventArgs e)
{
var test = HttpContext.Current.Request.Form;
}
Setting a breakpoint on the assignment to test, then stepping over it (with F10) when it is hit, you can see that test is indeed set to the post(back)'s form-values collection.
Accessing the Postback Control Values
Alternatively, you can access the postback control values by adding them to the session on postback, for example...
// ************code behind
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
Session["TextBox1"] = TextBox1.Text;
}
..., and accessing the session in the application error handler - for instance:
// ************Global.asax.cs
protected void Application_Error(object sender, EventArgs e)
{
// Use Session["TextBox1"].
}
A CodeVerge thread speaks to approach well - particularly Benson Yu's reply.
Related
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.
I've just started learning ASP.NET and I'm facing a problem with getting textbox values. I want to do a simple calculator with only 4 basic operations but what happens is that after I click the + sign and click Go, I see that I didn't store the first number at all. Second number is fine though. Here is a sample of my code.
public partial class deafult : System.Web.UI.Page
{
public TextBox output = new TextBox();
public double temp,tempAdd, calc;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnAdd_Click(object sender, EventArgs e)
{
tempAdd = Convert.ToDouble(output.Text);
output.Text = String.Empty;
}
//User enters another number after clicking Add button then clicks Proc
protected void proc_Click(object sender, EventArgs e)
{
temp = Convert.ToDouble(output.Text);
calc = tempAdd + temp;
output.Text = calc.ToString();
}
}
I debugged and tempAdd is always 0 but I get the number in temp. temp variables and calc is defined public.
You essentially have the problem with all of your variables being re-initialized on load of the page. Unlike winforms, web is stateless.
There are ways of persisting state between refreshes, however. The most obvious choice for your application would be to only go to the server once with the both values and what you want to do with them. ie One button click.
However, for personal edification, it may be worth looking up ViewState. This allows you to store values in an array of sorts and retrieve them even after a refresh.
There are also Session and Application level arrays in ASP.NET that work in similar ways.
Every time you call the page (by events) all your properties is initialized.
Try to do all your logic in one event or store your properties in manager / service / db.
In web (Asp.Net) on every postback properties will get cleared, try to use ViewState or Session variables to hold these values. Refer Asp.Net State Management concepts from MS.
Hope this may help you.
Web controls are State less so you should user session sate to hold the first value then do your stuff...
Ex:-
protected void btnAdd_Click(object sender, EventArgs e)
{
Session["tempAdd"] = output.Text;
output.Text = String.Empty;
}
protected void proc_Click(object sender, EventArgs e)
{
temp = Convert.ToDouble(output.Text);
string oldval=Session["tempAdd"] != null ?Session["tempAdd"].ToString() :"";
if(oldval!="")
tempadd=Convert.ToDouble(oldval);
calc = tempAdd + temp;
output.Text = calc.ToString();
}
I don't understand why or what I'm doing wrong, but I get a null reference exception when the follow code is executed in my Windows Phone 8.1 application:
First, the application navigates and passes the selectedStation to the next page...
Code from the MainPage:
// When an item is selected, go to the next page and pass info
private void listBoxStations_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// Get the selected station item
CompleteStation selectedStation = (CompleteStation)this.listBoxStations.SelectedItem;
this.Frame.Navigate(typeof(StationInformationPage), selectedStation);
// Make sure we set the selected index to -1 after item is selected so
// when we come back to page, no items are selected
this.listBoxStations.SelectedIndex = -1;
}
Here is the code that is getting the null error in the next page:
private CompleteStation station;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
this.navigationHelper.OnNavigatedTo(e);
this.station = (CompleteStation)e.Parameter;
AddInformation();
}
private void AddInformation()
{
this.txtStationTitle.Text = station.StationName;
// Add more information here
}
The error is specifically happening when I try to change the txtStationTile.Text to station.StationName.
If I take out the code that changes the textbox, and I step through the program, it shows that the station variable is not actually null by the end of the OnNavigatedTo method...
Any help would be greatly appreciated!
-Johan
It seems that it's not the station that's null, but the this.txtStationTitle.
You're doing everything in OnNavigatedTo while the page (XAML) including the TextBlock you're trying to change is not completely loaded, so the TextBlock is null and when you try to do this.txtStationTitle.Text, you get a NullReferenceException.
However, if you called AddInformation in Loaded event handler of the Page, then you'd be sure that the page is fully loaded and TextBlock would not be null anymore.
public SomePage()
{
this.InitializeComponent();
this.Loaded += SomePage_Loaded;
}
void SomePage_Loaded(object sender, RoutedEventArgs e)
{
AddInformation();
}
This type of exception is usually very easy to debug. Putting a breakpoint on the following line:
this.txtStationTitle.Text = station.StationName;
and examining this.txtStationTitle and station would make it really simple to find out what exactly is null.
I'm still new at this so I will try to explain my problem the best I can. English is not my first language so I apologize if I use some terms incorrectly.
I have a 100 line code that is executed every time a button is pressed. My problem is, I have 20 buttons and they all contain the same code (they are only slightly different in means of grabbing info from different source). Is there any way to do this instead of copying the same code too many times.
Basically my code is this:
private void button1_Click(object sender, EventArgs e)
{
//file data source url
sourceUrl = ("www.myurl.com")
//Grab data
code
code
code
//Store data
code
code
code
//Write data
code
code
code
}
Every button has the same code except for the "sourceUrl" part. If I want to add more buttons I have to copy>paste the whole code and my application is starting to get HUGE. Is there any way to shrink the code by only having the code once, and then calling an action or method every time the button is pressed. So instead of having 100 line code multiple time, I'll have one line code for each button and one 100 line code on the top that will be the source for that one line code.
Thanks in advance
Use the Tag property of your buttons to store the source url string and then set, for every button, the same event handler
private void buttonCommonHandler_Click(object sender, EventArgs e)
{
Button b = sender as Button;
CommonMethod(b.Tag.ToString());
}
private void CommonMethod(string sourceUrl)
{
// Execute the common code here....
}
You could set the common handler and the Tag using the form designer window or you could do that dynamically mimicking the code prepared for you by the designer in the InitializeComponent call
button1.Click += buttonCommonHandler;
button1.Tag = "www.myurl.com";
button2.Click += buttonCommonHandler;
button2.Tag = "www.anotherurl.com";
That's what functions are for. Use this layout:
private void YourFunc(string sourceUrl)
{
//Grab data
code
//Store data
code
//Write data
code
}
Now your buttons' event handlers look like this:
private void button1_Click(object sender, EventArgs e)
{
YourFunc("www.myurl.com");
}
private void button2_Click(object sender, EventArgs e)
{
YourFunc("www.myurl2.com");
}
Sure there is a way. Just make the whole function a function that takes the url as a string parameter. And then call that function from your code behind.
private void button1_Click(object sender, EventArgs e)
{
//file data source url
ProcessData("www.myurl.com");
}
private void ProcessData(string sourceUrl)
{
//Grab data
code
code
code
//Store data
code
code
code
//Write data
code
code
code
}
Here we can use use CommandName property, by passing URL in every button's CommandName property and passing it as a parameter to your Common Method to fetch data , So you can create a single function and call it through you btn_Click event .
<asp:Button ID="button1" runat="server" Text="clickMe"
CommandName="put your URL here" OnCommand="button1_Click" />
<%--OnClick="button1_Click" />--%>
See here we can pass your 'URL' in CommandName property ,few things to keep in mind , Here we are using OnCommand event rather than OnClick event of button , so that we can use 'CommandName' property here .1. OnCommand MSDN
2. Commandname MSDN
// private void button1_Click(object sender, EventArgs e)
private void button1_Click(object sender, CommandEventArgs e)
{
string sourceUrl = Convert.tostring(e.CommandName)
// Call function to grab data pass URL as parameter.
GrabDate (sourceUrl ) ;
So now we can get the URL value from button CommandName property .
3 . EventArgs Class
4 .CommandEventArgsClass
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Response.Redirect causes System.Threading.ThreadAbortException
ASP/C#.NET (web forms, not MVC)
UPDATE: Just found a related post (likely rendering this a duplicate): Why Response.Redirect causes System.Threading.ThreadAbortException?
~ ~ ~
After a good bit of research, I have come to the understanding that, in general, when using Response.Redirect(), it is better to pass FALSE for the second parameter, to avoid System.Threading.ThreadAbortException. (http://blogs.msdn.com/b/tmarq/archive/2009/06/25/correct-use-of-system-web-httpresponse-redirect.aspx)
My question is, "Is there a recommended way (pattern) for managing (namely skipping) processing in page events that fire after the redirect, when false is passed for the second parameter?"
This is mostly a problem for me when I am checking for and redirecting on an expired session in Page_Load(). It seems very tedious to have to perhaps set a "_Redirected" flag every time I redirect and then check that flag at the top of every event. I haven't had to worry about this in the past because I always passed TRUE for the second parameter, not knowing any better.
Below is some code showing what I don't want to have to do (check _Redirected before processing each event). Perhaps what I'm looking for is a better Session Expiration Processing pattern.
Any suggestions on how to improve this processing, would be greatly appreciated.
private bool _Redirected = false;
protected void Page_Load(object sender, EventArgs e)
{
if (Session["key"] == null)
{
Response.Redirect("SessionExpired.aspx", false);
Context.ApplicationInstance.CompleteRequest();
_Redirected = true;
}
}
protected void Page_PreRender(object sender, EventArgs e)
{
if (!_Redirected)
{
// do Page_PreRender() stuff...
}
}
protected void Button1_Click(object sender, EventArgs e)
{
if (!_Redirected)
{
// do Button1_Click() stuff...
Response.Redirect("Button1Page.aspx", false);
Context.ApplicationInstance.CompleteRequest();
_Redirected = true;
}
}
protected void Button2_Click(object sender, EventArgs e)
{
if (!_Redirected)
{
// do Button2_Click() stuff...
Response.Redirect("Button2Page.aspx", false);
Context.ApplicationInstance.CompleteRequest();
_Redirected = true;
}
}
~ ~ ~
[01/24/2013] In response to https://stackoverflow.com/users/2424/chris-lively (thank you, btw), here is simplified code that I believe is similar to what you tested. I am still seeing Button1_Click() execute on post back after the Response.Redirect(url, false) with .CompleteRequest() in Page_Load().
protected void Page_Load(object sender, EventArgs e)
{
if (this.IsPostBack)
{
Response.Redirect("Redirect.aspx", false);
Context.ApplicationInstance.CompleteRequest();
}
}
protected void Button1_Click(object sender, EventArgs e)
{
Response.Write("Button1 clicked!");
}
This behavior is corroborated by this response https://stackoverflow.com/a/12957854/1530187 to the similar post I noted above in my update.
Any idea what I'm doing wrong that would cause the page to continue executing after redirect?
You referenced a pretty good article, but your code doesn't reflect what the author suggested as a way to do this "correctly". Namely:
protected void Page_Load(object sender, EventArgs e)
{
if (Session["key"] == null)
{
Response.Redirect("SessionExpired.aspx", false);
Context.ApplicationInstance.CompleteRequest();
}
}
UPDATE
I put together a very simple sample application. All it had was two form pages.
The first page had a button on it that did a response.write. I put a breakpoint on this line. In the page_load method I put a redirect followed immediately by a call to CompleteRequest. This redirect occured was set to occur if the page was posting back.
All the second page did was emit "hello"
I then ran the application, which pulled up the first form. I clicked the button. The break point was never hit and it redirected. This was exactly what I expected it to do. Namely, the page_load method caught the postback, performed a redirect and completed the request immediately without further processing of the page.
This means that there is absolutely no reason to put the if (!_Redirected) code in each of your button clicks. All you need to do is copy/ paste the code I have at the top of this answer. It will prevent those clicks from being called.