Okay so I'm quite new to ASP.NET and the MasterPage concept and there's an error I just can't figure out.
This is a part of my default.aspx:
<asp:Content ID="ContentLoginContent" ContentPlaceHolderID="LoginContentPlaceHolder" runat="server">
<div id="ContentLoginDiv">
You've got <asp:Label ID="MemberCreditLabel" runat="server" Text="0"></asp:Label> credits.
</div>
This is the relevant part of my default.aspx.cs:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Init(object sender, EventArgs e)
{
}
protected void Page_Load(object sender, EventArgs e)
{
if (User.IsInRole("Authenticated"))
{
MemberCreditLabel.Text = "hello ";
}
}
}
I get a Nullref exception on MemberCreditLabel. It gets detected with intelliSense. I think the problem could be that the ContentPlaceHolder "ContentLoginContent" only shows when logged in. This is a part of my MasterPage:
<asp:LoginView ID="MemberLoginView" runat="server">
<AnonymousTemplate>
<asp:Login ID="LogInBox" runat="server" Height="137px" style="margin-left: 0px"
Width="16px">
</asp:Login>
</AnonymousTemplate>
<LoggedInTemplate>
Welcome <asp:LoginName ID="MemberLoginName" runat="server" /> !
<asp:LoginStatus ID="MemberLoginStatus" runat="server" />
<asp:ContentPlaceHolder ID="LoginContentPlaceHolder" runat="server">
//Is this the problem?
</asp:ContentPlaceHolder>
</LoggedInTemplate>
</asp:LoginView>
What I want to do is to show a credit amount stored in a database. The function for retreiving the data I want works. I take the user name of the currently logged in user and want to get the credit amount associated with the user. But this strange error with the label halts me completely.. It's probably got to do with a concept of MasterPages that I haven't stumbled across yet. Any ideas?
Apparently this is by design:
This is by design. The content control replaces the content of the contentplaceholder control which is inside a template. Thus the textbox actually gets instatiated in a template and thus needs to be looked up using FindControl - direct access will not be available.
Thanks,
The WebPlatform and Tools Team.
However, using a recursive FindControl, I wasn't able to actually get hold of the control inside the LoggedInTemplate - indeed in the markup of the Page, ReSharper was complaining that it couldn't resolve the symbol "LoginContentPlaceHolder" - i.e. it couldn't find the content placeholder correctly on the MasterPage.
Is there any way you could display the credits on all authenticated pages?
Or, you could wrap the LoginView with just a LoggedInTemplate containing the credit count into a usercontrol, and drop that inside the content placeholder.
Related
I have a simple web page that contains a Literal, now I want to create a form tag in code behind.
This is an example:
if (IsPostBack)
{
Literal1.Text = "form submit";
}
else
{
Literal1.Text = "<form id='myFrom' runat='server' action='default.aspx'
method='POST'><input type='submit' value='click here'/></form>";
}
This code create the form, but when I click the submit button, it doesn't go through IsPostBack path. Why?
Note that I need it to be created and sent as an string, because I want to use it in ajax for example.
IsPostBack is only enabled when the POST request originates from ASP.NET's __doPostBack() function. See How to use __doPostBack() for how to create an async postback request with JavaScript.
An ASP.NET web form is already an HTML form and encompasses all of your controls. You are nesting a form within a form which is not legal HTML.
I'd suggest you replace your nested form with a simple button. In the click handler for the button, redirect to default.aspx.
As indicated by John Wu, you don't want to implement your code this way. Nested forms -- while browsers forgive them -- are just not the way to go, especially with ASP.Net WebForms. Sure, I was able to get your code to work, BUT if you need to ajaxify your page so that it works with the WebForms postback model, then it would be much better to use the UpdatePanel control (in conjunction with the ScriptManager control).
ASP.Net WebForms is predicated on only having a single Form element used on a page, as it relates to its postback model, so you'll want to work within that constraint.
Here's some code to demonstrate the use of the UpdatePanel to ajaxify a WebForm (and take advantage of PostBack):
...the .ASPX page:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="NestedForm_Question.aspx.cs" Inherits="StackOverflowAspNetQuestionAnswers.NestedForm_Question" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager" runat="server" />
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Literal ID="Literal1" runat="server" />
<asp:Button ID="SubmitButton" Text="Submit" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
...the associated code-behind class:
public partial class NestedForm_Question : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
SubmitButton.Click += SubmitButton_Click;
}
void SubmitButton_Click(object sender, EventArgs e)
{
Literal1.Text = "form submit";
}
}
You can see that in the code-behind class, the code that would need to be written to set the value of the literal control after the Button is clicked is the same whether the page is ajaxified or not.
I've changed my code to this:
if (Context.Request.Form.HasKeys()) // instead of if(IsPostBack)
{
Literal1.Text = "isPostBack";
}
else
{
Literal1.Text = "<form id='myFrom' runat='server' action='default.aspx' method='POST'><input type='submit' name='submitbtn' value='click here'/></form>";
}
Using different examples, I didn't find any exception to this. and it works well.
Any idea about this solution?
Note that in this way at least one of our elements in the form should have the name property.
I am unfamiliar with C#/ASP/.NET (learning as I go), so it is very likely that I am going about this in an inferior way, in addition to the problems with my current way of doing this. I will try to be as clear as possible (maybe overly so...).
I have a form with a textbox to take in a list of server hostnames, separated by line returns. Upon pressing the submit button, it uses PostBackUrl="~/btil_Info.aspx". In btil_info.aspx.cs codebehind, I get the info from said textbox (hostnames_tb) from the previous form in Page_Load() using:
string hostnames = ((TextBox)Page.PreviousPage.FindControl("hostnames_tb")).Text;
Within Page_Load(), I loop through this list of hostnames and build a form containing several fields for each host (a few textboxes and a dropdown menu for each host). After filling out these fields, upon pressing the Submit button here which calls Submit_Click() in the same codebehind, the page appears to reload because Page_Load is called again before Submit_Click() is executed. In doing so, the the filled form data is lost and the list of hostnames is also lost.
At an earlier stage in development, I had this all on the very first form page, and the submit button didn't call PostBackURL, it simply called Submit_Click(), which worked perfectly fine. The page didn't reload, the form stayed on the page, and I didn't lose data. But as it is now, the button works the same way. The only difference (that I see) being that this troublesome page is reached via the previous form calling PostBackURL.
I don't believe there's any point where anything should be requesting a page refresh/reload. I don't actually care if the page refreshes/reloads as long as the form data is posted and as long as the list of hostnames from the previous form is also retrievable. I just need to be able to access the form data and list of hostnames so that I can pass it to another method of mine that will update a SharePoint list (the code for that part is already working, though). I tried making the hostnames string a class variable in the 2nd codebehind (btil_Info.aspx.cs) and setting it as soon as soon as the page loads if it is empty, but apparently it does not persist over the page reload and is set back to null.
Here's some snippets of code that I hope will be of some help:
First page, add_BTIL.aspx:
<form id="form1" runat="server">
<div>
<asp:TextBox ID="hostnames_tb" runat="server" Rows="20" TextMode="MultiLine" Width="225px"></asp:TextBox>
<br />
<asp:Button ID="Submit" runat="server" PostBackUrl="~/btil_Info.aspx" Text="Submit" />
<br />
<asp:Literal ID="result" runat="server"></asp:Literal>
<br /><br />
<textarea id="hostnames_textarea" cols="25" rows="20" name="hostnames" title="Hostnames"></textarea></div>
</form>
First page codebehind, add_BTIL.aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Submit_Click(object sender, EventArgs e)
{
string hostnames = hostnames_tb.Text;
/*
* Etc.
*/
}
Second page, btil_Info.aspx:
<form id="hosts_form" runat="server">
<p>
<asp:Button ID="Submit" runat="server" Text="Submit" OnClick="Submit_Click" Height="26px" UseSubmitBehavior="False" /><br />
<asp:Literal ID="result" runat="server"></asp:Literal><br />
</p>
<br />
</form>
^ In this form, I read somewhere in my searches that UseSubmitBehavior="False" would prevent a page reload, but it did not help. I didn't use it in my earlier version anyway, and did not have this issue.
Second page codebehind, btil_Info.aspx.cs:
protected void Page_Load(object sender, EventArgs e)
{
string hostnames = ((TextBox)Page.PreviousPage.FindControl("hostnames_tb")).Text;
// etc.....
}
protected void Submit_Click(object sender, EventArgs e)
{
// etc.....
}
Many thanks for any help!
If you're posting from add_BTIL.aspx to btil_Info.aspx then the Submit_Click function in file add_BTIL.aspx.cs will never be called.
Based on the limited markup you've given us for the btil_Info.aspx page...
If you aren't rendering your host names list inside of server controls inside the form id="hosts_form" then when you hit the submit button nothing is going to be posted to your Submit_Click function.
Personally I don't like post from one page to another so here are some suggestions below.
If you want to do a multi-page wizard then you might consider the asp.net wizard control.
Or if you want to keep it simple, use two asp Panel controls and show the first one, post the data, and then hide the first and show the second one.
I started to build a website using Umbraco and I noticed that button click events (and probably other events) are not working.
I created simplest usercontrol with one button, added it to a page, When I debug it the Page_Load is called (breakpoint being hit), but not button click.
The code is very standard, but here it is:
.aspx file
<%# Control Language="C#" AutoEventWireup="true" CodeFile="TestControl.ascx.cs" Inherits="usercontrols_TestControl" %>
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
and code behind:
protected void Button1_Click(object sender, EventArgs e) {
Label1.Text = "Button clicked!";
}
Where can be the problem?
Make sure you are wrapping your body with <form runat="server">...</form> tags, the user control/macro should be inside the form tags. Also ensure that you are adding the user control correctly. To help you out with this, here are a few resources:
A demo by Niels Hartvig. (Niels is using a current Umbraco version.)
Tim Geyssens' screencast. (Tim is using an older version of Umbraco in the screencast (not 4.7.*), but there isn't much difference.)
Step-by-step instructions by Skiltz.
I am trying to create a dynamic UI using UpdatePanel of AJAX toolkit.
Let me explain the context of my application a bit. There are many profiles. Each profile has a number of product classes. Each product class has a number of products.
I am implementing a comparison of products.
Profiles are represented by RadioButtonList (dynamically created). For each product class of selected profile a DropDownList need to
be dynamically created that allows user to select a product of that class.
Everything is working fine on the first selection. However when I try to select another product and click submit the second time, the following error is thrown:
Microsoft JScript runtime error:
Sys.WebForms.PageRequestManagerServerErrorException: Invalid postback
or callback argument. Event validation is enabled using in configuration or <%# Page
EnableEventValidation="true" %> in a page.
Any hints on why this error is thrown would be very helpful.
protected void Page_Load(object sender, EventArgs e)
{
pnlDynamic.Visible = false;
if (!this.IsPostBack)
{
LoadProfiles(); //Data binding is done for radio button list
}
else
{
btnSubmit.Enabled = true;
GenerateProductUI(ProfileID); //DropDownLists are dynamically created and populated from database
//ProfileID is the selected profile id
}
}
<asp:UpdatePanel runat="server" id="UpdatePanel" updatemode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger controlid="rblProfiles" eventname="SelectedIndexChanged" />
</Triggers>
<ContentTemplate>
<asp:Panel ID="Panel1" runat="server">
<asp:RadioButtonList ID="rblProfiles" runat="server" AutoPostBack="True"
onselectedindexchanged="rblProfiles_SelectedIndexChanged">
</asp:RadioButtonList>
</asp:Panel>
<br />
<asp:Panel ID="pnlDynamic" runat="server" Visible="false">
<asp:Panel ID="Panel2" runat="server">
<asp:Table ID="table" runat="server"/> <!-- Product dropdowns generated in table -->
</asp:Panel>
</asp:Panel>
<br />
</ContentTemplate>
</asp:UpdatePanel>
<asp:Button ID="btnSubmit" runat="server" Text="Submit" onclick="btnSubmit_Click" CssClass="btnSubmit" AutoPostBack="True" />
<asp:UpdatePanel runat="server" id="UpdatePanel1" updatemode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger controlid="btnSubmit" eventname="Click" />
</Triggers>
<ContentTemplate>
<asp:Panel ID="pnlResult" runat="server" Visible="false">
<!--Result displayed-->
</asp:Panel>
<br />
</ContentTemplate>
</asp:UpdatePanel>
IMPORTANT! EVERYONE WHO EVER DISABLES EVENT VALIDATION SHOULD UNDERSTAND WHAT HE IS DISABLING!
Imagine that you have a blogging application (or a banking application) and there is a list of comments (or bank accounts) all users can see the comments (or the accounts) but only moderators (or managers) can delete them. So you write a check to switch the delete button visible property depending on the access of the user. Users who are not moderators (managers) cannot delete the comment (account). Problem solved.
HOWEVER if you disable event validation a malicious user can send a post request claiming to have pressed the delete button despite the fact that it was never enabled for him. Normally the event validation would kick in and produce an exception but if it is disabled ASP.NET would not check if the button was visible and will just run the button click handler code and the comment (account) would be deleted. This can be prevented if you check if the user can delete in the button click event but you should also consider that another developer may come later and add another button (edit?) without noticing that event validation was disabled. Also now all other buttons on the page require the appropriate checks. Be very careful if you disable event validation!
The error occurs because you are triggering a postback from a control which does not exist when the original page was rendered. One way to fix it would be to disable event validation for this page but you should make sure to check the credentials of the user requesting the change in the event itself otherwise it is a security issue because a user will be able to "press" a button that was not rendered at all (for example on products he does not have access to).
You can disable event validation through the page directive:
<%# Page EnableEventValidation="false" ... %>
I believe it is also possible to set the update mode of the update panel to always instead of conditional which maybe will fix the issue (can you try it and tell us?) but this will increase the data sent over the network. If it is a good trade off depends on your use case, on the number and size of the update panels you have on the page (the more you have the worse). If it is an internal app or this UI is accessed relatively rarely I would go for this approach (assuming it works because I have not validated that).
BTW this is not actually a script error. You are getting a client side script error simply because the error surfaces through an AJAX request. This is purely a server error that is raised because of a potential security issue with your code.
Add <%# Page EnableEventValidation="false" %> at the top of the page.
Once dynamic dropdown lists are created you have to recreate them or any dynamically created control on every page init or page load. In such case you don't need to use EnableEventValidation="false".
protected void Page_Load(object sender, EventArgs e)
{
pnlDynamic.Visible = false;
if (!this.IsPostBack)
{
LoadProfiles(); //Data binding is done for radio button list
}
else
{
btnSubmit.Enabled = true;
}
GenerateProductUI(ProfileID); //DropDownLists are dynamically created and populated from database
//ProfileID is the selected profile id
}
Or just move GenerateProductUI(ProfileID) from Page_Load to Page_Init
I am trying to get a modal popup to work, it needs to be triggered in the Code behind.
<asp:Button ID="btnModalPopUp" runat="server" Text="Button" Style="display: none" />
<asp:Panel ID="pnlModalPopup" runat="server" CssClass="modalPopup" Style="display: none"
Width="233px">
<div id="Div1" runat="server" cssclass="title">
Modal text here.
<asp:TextBox ID="txtEditComments" runat="server"></asp:TextBox>
</div>
</asp:Panel>
<cc1:ModalPopupExtender ID="modalMessage" runat="server" TargetControlID="btnModalPopUp"
PopupControlID="pnlModalPopup" BackgroundCssClass="modalBackground" DropShadow="true"/>
Code behind:
protected void Page_Load(object sender, EventArgs e)
{
modalMessage.Show();
}
Even though it hits the "modalMessage.Show();" code it doesn't show the modal panel.
Two solutions:
The first solution:
Remove Style="display:none" from the pnlModalPopup.
The first solution is will cause the popup to "flash" on the screen when the page first loads, and then quickly disappear.
The second solution:
protected void Page_Load(object sender, EventArgs e)
{
pnlModalPopup.Style["display"] = "block";
modalMessage.Show();
}
Recommendation:
I would recommend using the second solution, that way the modal popup doesn't flicker and then disappear.
Edit: I just tested your code:
I just tested your code in a simple page that contained only the code that you provided...It worked like expected.
Check the following:
Is your modal popup is defined in an UpdatePanel that is conditionally updated?
Check to make sure that the modal popup isn't defined in a Panel that has it's visibility set to false.
If that doesn't work, then check if the modal popup is actually in the source code of the rendered web page.
Listen to Chris's comment as it is needed:
display:none is cosmetically needed,
otherwise the popup will display when
the page is loading, then will quickly
disappear while the ModalPopupExtender
kicks in and hides it.
We had to make ours show like this:
pnlModalPopup.Visible = true;
modalMessage.Show();