Having just added a new button in my web application, I get an error when clicking on it, and I'm wondering if this is related to misplaced code. I will describe what/where I did, briefly. Thanks very much.
In ascx file:
<asp:Button ID="btn_rezerv" runat="server" Text="Reserve film" OnClick="btn_rezerv_Click"/>
In the ascx.cs file:
namespace CinProj.UserControls
{
public partial class FilmsList : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
PopulateControls();
}
private void PopulateControls()
{
string categId = Request.QueryString["CategID"];
string filmId = Request.QueryString["FilmID"];
....
if (categId != null)
{
.....
}
if (filmId != null)
{
......
Button btn_rezerv = (Button)item.FindControl("btn_rezerv");
}
}
protected void btn_rezerv_Click(object sender, EventArgs e)
{
string fid = Request.QueryString["FilmID"];
ShoppingCartAccess.AddItem(fid);
}
}
}
"Server Error in '/' Application.
Invalid postback or callback argument. Event validation is enabled using in configuration or <%# Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation. "
Another problem could be because your PopulateControls method should probably only be called when during the Page Load when it's not a PostBack. I can't tell from above, but to me it looks like it only needs done on Load. Try wrapping that call with this:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
PopulateControls();
}
}
It's likely the result of making some sort of client change that the server doesn't know about. Many times this is the result of changing values in a dropdown in JavaScript, for example.
To fix, you could:
Do away with using JavaScript for said modification
Use an UpdatePanel and add your control to it. If the client needs to make a change, trigger the UpdatePanel's update in order for the control's viewstate to update.
Related
The scenario is very simple. I have an aspx page with a user control. I want to set a value and get a response from usercontrol on aspx page's pageload. The SET job is done, but can't GET the response. It's always empty. I tried two methods, but none of them worked.
ASPX PAGE
<uc1:ucContent ID="Content1" runat="server" />
CODE BEHIND
protected void Page_Load(object sender, EventArgs e)
{
// SET job is working without any problem
Content1.ItemName = "X";
//METHOD ONE:
Page.Title = Content1.MetaPageTitle;
//METHOD TWO:
HiddenField hdnPageTitle = (HiddenField)Content1.FindControl("hdnMetaPageTitle");
Page.Title = hdnPageTitle.Value;
}
USER CONTROL
protected void Page_Load(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(itemName))
{
// GET DATA FROM DB
// METHOD ONE:
hdnTitle.Value = DB.DATA;
// METHOD TWO:
metaPageTitle = DB.DATA;
}
}
private string metaPageTitle;
public string MetaPageTitle
{
// METHOD ONE:
get { return metaPageTitle; }
// METHOD TWO:
get { return hdnTitle.value; }
}
EDIT
itemName is a UserControl property to get a value from Parent Page:
private string itemName;
public string ItemName
{
set { itemName = value; }
}
Thanks for your kind help in advance!
I think that the problem is that the page's Page_Load is triggered before the UserControl(Have a look: asp.net: what's the page life cycle order of a control/page compared to a user contorl inside it?).
So you could set the property in Page_init:
In your UserControl:
protected void Page_Init(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(itemName))
{
// GET DATA FROM DB
hdnTitle.Value = DB.DATA;
}
}
Now this should work in your page's Page_Load:
Page.Title = Content1.MetaPageTitle;
Normally i would prefer another kind of communication between a Page and a UserControl. It's called event-driven communication and means that you should trigger a custom event in your UC when the MetaPageTitle changed (so in the appopriate event-handler).
Then the page can handle this specific event and react accordingly.
Mastering Page-UserControl Communication - event driven communication
I'm gonna post some more code to show exactly what I'm trying to do,
I'm adding the button using programming code and not markup but the OnClick won't work (giving the following error:
System.Web.UI.WebControls.Button.OnClick(System.EventArgs)' is inaccessible due to its protection level.
Button btnopslaan = new Button();
btnopslaan.Text = "Opslaan";
btnopslaan.ID = "btnOpslaan";
btnopslaan.CssClass = ".opslaan";
btnopslaan.Click += new EventHandler(btnopslaanClick);
btnopslaan_arr[btn_count] = btnopslaan;
add_button(btnopslaan);
protected void btnopslaanClick(object sender, EventArgs e)
{
Debug.WriteLine("success");
}
I just can't find out why this isn't working.
Anyone who can help me out?
You need to use OnClick for server side clicks rather than OnClientClick
Either you can use it inline >
<asp:Button id="btnopslaan" runat="server' OnClick="btnopslaanClick" />
Or in Code behind >
btnopslaan.Click+=new EventHandler(btnopslaanClick);
or you make it a postback call to the server. in your
aspx write:
<asp:Button runat="server" ID="buttonOpslaan" Text="opslaan" ></asp:Button>
codebehind write this:
protected void Page_Init(object sender, EventArgs e)
{
buttonOpslaan.Click += new EventHandler(buttonOpslaan_Click);
}
// mind: this method can be private
void buttonOpslaan_Click(object sender, EventArgs e)
{
//do something
}
or handle it with the AutoEventWireUp (recommended) like:
<asp:Button runat="server"
ID="buttonOpslaan"
OnClick="buttonOpslaan_Click"
Text="opslaan" ></asp:Button>
// mind: this method cannot be private, but has to be protected at least.
protected void buttonOpslaan_Click(object sender, EventArgs e)
{
//do something
}
or do it completely from code behind:
// note: buttonOpslaan must have an (autoassigned) ID.
protected void Page_Init(object sender, EventArgs e)
{
Button buttonOpslaan = new Button();
buttonOpslaan.Text = "opslaan!";
buttonOpslaan.Click += new EventHandler(buttonOpslaan_Click);
form1.Controls.Add(buttonOpslaan);
}
protected void buttonOpslaan_Click(object sender, EventArgs e)
{
//do something
}
or handle it clientside with javascript in your ASPX (it will not reach the server)
<script type="text/javascript">
function buttonOpslaan_Click(){
alert("test");
return false;
}
</script>
<asp:Button runat="server"
ID="buttonOpslaan"
OnClientClick="buttonOpslaan_Click()"
Text="opslaan" ></asp:Button>
Update: (by comments)
if you add the control via an eventhandler (like the onchange event of a dropdownlist), the control is 'lost' on next postback, or even as soon as the Page is send to the client (due to the stateless (there is no mechanism to maintain the state of application) behaviour and lifecycle of .Net).
So simply adding a control once is never going to work.
That means you have to rebuild the control every time a postback occurs. My preferred way to do this is store a list/document somewhere that descrbes what controls must be created each time. Possible locations are, from worse to good (IMHO):
Session
Viewstate
Cache
XML/IO
Database
After all, you are posting "data" to the server (that represents a control) and you want to save that for further use.
If the controls to be created aren't that complex you could implement a Factory Pattern like a WebControlFactory that stores only a few properties in a List or Dictionary, which is read every time to recreate the controls again (and again, and again, and again)
btnopslaanClick should be client side, in the .aspx itself have:
<script type="text/javascript">
function btnopslaanClick() {
alert("success");
}
</script>
btnopslaan.Click+=new EventHandler(btnopslaanClick);
protected void btnopslaanClick(object sender, EventArgs e)
{
Debug.WriteLine("succes");
}
In my master page, I'm loading a variable in the session like this:
public partial class TheMasterPage : System.Web.UI.MasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
ViewUserPreferences SessionUserPreferences = new ViewUserPreferences();
SessionUserPreferences = UserPreferences.GetUserPreferencesFromDB(6);
}
}
}
Then, in the code behind of a file, I have this:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
var test = Session["SessionUserPreferences"];
}
}
But when I debug, test is null. What's causing the problem?
Also, if I put a break point in the master page, it doesn't trigger when I run the aspx page; is this normal?
Thanks.
First thing you are missing the assignment part for UserPreferences.GetUserPreferencesFromDB(6) to the Session object. (I read the comments for #Greg's answer and you mentioned that even after that it is not working.)
Second, Master Page's Page_Load Event is triggered after the Current Page's Page_Load Event, hence the value of Session["SessionUserPreferences"] is null in Current Page's Page Load event since it is not set yet.
Check this link for further information on Page Events:
http://msdn.microsoft.com/en-us/library/dct97kc3.aspx
You have to do Session["SessionUserPreferences"] = something; somewhere before you attempt to retrieve that. Are you setting it somewhere else that you didn't show?
I am trying to raise a click event from User control and handle it on the containing page. The problem I have is, when I click the button 'imgstep1' on the user control, the code behind imgstep1_click event triggers and but the 'btnHandler' event is alway null. Hence it doesnt call the parent event.
Any help on this will be much appreciated.
My User Control Code is :
.ascx code:
<asp:ImageButton ImageUrl="./images/step1.gif"
ID="imgstep1" runat="server"
OnClick="imgstep1_Click"/>
.ascx.cs code :
public delegate void OnImageButtonClick();
public event OnImageButtonClick btnHandler;
protected void imgstep1_Click(object sender, ImageClickEventArgs e)
{
if (btnHandler != null)
btnHandler();
}
.aspx page code:
protected void Page_Load(object sender, EventArgs e)
{
ucStepHdr.btnHandler += new StepsHeader.OnImageButtonClick(ucStepHdr_btnHandler);
}
void ucStepHdr_btnHandler()
{
Response.Write ('test');
}
The code looks simple enough to work correctly. The only reason that btnHandler is null could be because the event registration code in the aspx page is not called.
Is there a post back ? Are you sure you are adding the event EACH TIME the page loads ???
ucStepHdr.btnHandler += new StepsHeader.OnImageButtonClick(ucStepHdr_btnHandler);
If you remove OnClick="imgstep1_Click" and you put this in your ascx.cs
protected ImageButton imgstep1;
protected override void OnInit(EventArgs e)
{
this.imgstep1.Click += new ImageClickEventHandler(imgstep1_Click);
}
Does this method of wiring up your event work?
It looks like it should work... can you step through the code in the debugger, and see what the value of ucStepHdr.btnHandler is as soon as you set it in Page_Load? (Just an aside, traditionally these are set in init rather than load, but this isn't your issue.)
Is it recommended to check the Page.IsPostBack in a user control Page_Load Event like
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
}
}
I am getting wierd results
Edit ~ Here is the thing. When the main form is loaded, I use Request.QueryString to get the customer id which I then place in a SESSION variable.
On the control Load event I read the SESSION variable to get the data for that customer. So, do I need to check PostBack at the control level?
Edit ~ Here is the load event of the control
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//Getting and storing the customer account number
if (string.IsNullOrEmpty((string)Session["CustomerNumber"]))
{
Session["CustomerNumber"] = cust.GetCustomerNumber(myHelper.GetCustomerIDFromQueryString());
LoadProductData();
}
}
}
Here is the myHelper Class
static class myHelper
{
public static Guid GetCustomerIDFromQueryString()
{
//Getting the GUID (used as customerid in CRM) from the URL request of the selected account.
return Sql.ToGuid(System.Web.HttpContext.Current.Request["ID"]);
}
}
}
If you use "!IsPostBack" in page load, when the user click other control it do a postBack, so you don't get your data.
I hope that helps you.
Just checking it for no reason? Absolutely not. If you should do something only on first load and not on subsequent post backs then it's the pattern that should be used.
Are you sure that you will always have a "CustomerNumber" already stored in the Session by the time you get to your page? Is there any rhyme or reason that you can find as to when you get data and when you don't?