I'm creating a website which allows users to log in. After logging in successfully, user's name should be displayed across each page, for example, at the top right corner. I have a ContentPlaceHolder on Master Page. An h3 tag would then be created and added into this ContentPlaceHolder.
Master Page:
<asp:ContentPlaceHolder runat="server" ID="UserNamePlaceHolder">
</asp:ContentPlaceHolder>
Login Page:
<%# MasterType VirtualPath="~/Master" %>
Login Class:
protected void Login_LoggedIn(object sender, EventArgs e)
{
ContentPlaceHolder userNamePlaceHolder =
(ContentPlaceHolder)Master.FindControl("UserNamePlaceHolder");
var h3 = new HtmlGenericControl("h3");
h3.InnerHtml = login.UserName;
userNamePlaceHolder.Controls.Add(h3);
}
I did debugging step by step. Nothing went wrong: no null or empty value, each variable was created. However, the user name was not displayed at all. Does anyone have an idea?
A cleaner and better approach would be to create a public property on the Master page:
public string UserName
{
get
{
return Literal1.Text;
}
set
{
Literal1.Text = value;
}
}
That's it place the literal with ID Literal1 anywhere you want on the master page:
<asp:Literal runat="server" ID="Literal1" />
You are already adding Master directive for strongly typing Master class, so now your login class would look like this:
protected void Login_LoggedIn(object sender, EventArgs e)
{
Master.UserName = login.UserName;
userNamePlaceHolder.Controls.Add(h3);
}
Hope this helps.
Related
I have a ASP.NET page called customer.aspx which has a user control customerdetails.ascx inside of it. This user control reads data from the database and populate some fields. If the loading is successful (if there is some data), the user should stay on the page. Otherwise the page should be redirected to a different page. This redirection is done in the container customer.aspx page and not in the control.
What are the ASP.NET page cycle events (Page_Load Vs Page_Init) that I should use for customer.aspx and customerdetails.ascx for the above logic to work?
If you've established that both options work functionally, then, for performance, you should prefer Page_Init.
If you might end up with a redirect, then you want to give the server the chance to do that redirect as soon as possible in the page lifecycle, to avoid using resources on lifecycle steps that might not be necessary.
I was rereading this - https://web.archive.org/web/20210330142645/http://www.4guysfromrolla.com/articles/092904-1.aspx, old, but good. I think you should be able to do what you need from the Page_Load event of customer.aspx because user controls are loaded by then. simply check the user control's controls for values and redirect, or not.
edit:
Actually, I think it depends. controls prob have to be preloaded, which changes things.
If we need our dynamically added controls to maintain their view state it is paramount that these controls be added before the Load View State stage. That is, these controls must exist within the page's control hierarchy before the view state is loaded. There's only one stage before Load View State - Initialization. That means, if we want our dynamic controls to persist view state we must add them to the control hierarchy in the page's Init event.
One way to make the user control accessible (answer at bottom): https://forums.asp.net/t/1674095.aspx?Loop+through+User+Controls+in+Content+Page
edit:
User Control
<h4>The User Control</h4>
<div>
<asp:Label ID="lblUserCtrl" runat="server" Text="Label"></asp:Label>
</div>
.cs
public partial class Testing_Controls_TestCtrl : System.Web.UI.UserControl
{
// public properties
public Label lbl
{
get { return lblUserCtrl; }
set { lblUserCtrl = value; }
}
public bool isLoaded;
// end public properties.
protected void Page_Init(object sender, System.EventArgs e)
{
lblUserCtrl.Text = "User ctrl loaded at: " + DateTime.Now;
isLoaded = true;
}
protected void Page_Load(object sender, EventArgs e)
{
}
}
container page:
note: I still had to register the control even though I loaded it from code.
<%# Register Src="~/Testing/Controls/TestCtrl.ascx" TagPrefix="uc1" TagName="TestCtrl" %>
...etc...
<form id="form1" runat="server">
<h4>The Container Page</h4>
<div>
<asp:Label ID="lblContainerLabel" runat="server" Text="Label"></asp:Label>
</div>
<br />
<hr />
<asp:PlaceHolder ID="ph1" runat="server"></asp:PlaceHolder>
</form>
.cs
public partial class Testing_user_control_test : System.Web.UI.Page
{
private bool ucIsLoaded;
protected void Page_Init(object sender, System.EventArgs e)
{
Testing_Controls_TestCtrl c = (Testing_Controls_TestCtrl)Page.LoadControl("~/Testing/Controls/TestCtrl.ascx");
ph1.Controls.Add(c);
c.lbl.Text += "<br />This is text appended to the user control by the container page.";
ucIsLoaded = c.isLoaded;
}
protected void Page_Load(object sender, EventArgs e)
{
lblContainerLabel.Text = "Container page loaded at: " + DateTime.Now + "<br />The user control is loaded: " + ucIsLoaded.ToString().ToUpper();
}
}
I am trying to use ViewState to retain my textbox's input during a postback. Here's the code:
private Label store_Incident_Number = new Label();
private TextBox Incident_Number = new TextBox();
protected void Page_Load(object sender, EventArgs e)
{
if (ViewState["Incident_Number"] != null)
{
store_Incident_Number.Text = "TEST" + (string)ViewState["Incident_Number"];
Panel1.Controls.Add(store_Incident_Number);
}
}
void Page_PreRender(object sender, EventArgs e)
{
ViewState.Add("Incident_Number", Incident_Number.Text);
}
above code located in my default.aspx.cs (code behind). The Panel1 is an asp control some where on the web page outside of a form tag. I am trying to follow this example: https://msdn.microsoft.com/en-us/library/ms227551(v=vs.85).aspx
I was hoping the Incident_Number textbox's text is saved onto the label after the page is postback, but it doesn't seems to work and I couldn't figure out the problem. Note that the textbox is dynamically added to the form of the page and is recreated every postback. My question is how I code to retain the textbox's value after the page is being postback?
EDIT: Fixed! Please see my accepted answer. Also, any eventhandler
or other process that have potential to trigger another postback
during Page_Init will refresh your value saved in viewstate (i.e. saved text is gone).
As I mentioned in my comment, you're not letting the WebForms system work for you. Here's an example of a form with dynamically created controls maintaining viewstate. Per your description, the panel is outside the form.
When the page is displayed, you can enter new text and click submit repeatedly. The TextBox value will automatically be retained.
Default.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
</form>
<asp:Panel ID="Panel1" runat="server"></asp:Panel>
</body>
</html>
Default.aspx.cs
using System;
using System.Web.UI.WebControls;
public partial class _Default : System.Web.UI.Page
{
private Label store_Incident_Number = new Label();
private TextBox Incident_Number = new TextBox() { ID = "TextBox1" };
private Button SubmitButton = new Button() { ID = "Button1", Text = "Submit" };
protected void Page_Init(object sender, EventArgs e)
{
// what is created during this event has viewstate restored to it
Panel1.Controls.Add(store_Incident_Number);
form1.Controls.Add(Incident_Number);
form1.Controls.Add(SubmitButton);
}
protected void Page_Load(object sender, EventArgs e)
{
// the viewstate has already been restored so you can access the content of the TextBox
store_Incident_Number.Text = Incident_Number.Text;
}
}
That happens because the page load method runs before the prerender. You can Google asp.net page lifecicle to find more details.
What you are basically doing here is loading the label value before adding it in the viewstate.
Also, it would help if you could tell us how exactly are you making the postback. Because click events for example, are also a part of the page lifecicle and that might change a few things.
I'm trying to access a hiddenfield value from my masterpage that is set in my child aspx page, but cannot access it the masterpage codebehind page_load event.
Child aspx page:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="Server">
<telerik:RadStyleSheetManager ID="RadStyleSheetManager1" runat="server">
</telerik:RadStyleSheetManager>
<div class="center_content">
<div style="text-align: left">
<h2>
</h2>
</div>
<div style="text-align: left">
<uc1:Chart ID="Chart1" runat="server" />
</div>
</div>
<asp:HiddenField ID="hid1" runat="server" Value="Satellite Availability % Report" />
Master page:
<asp:Label runat="server" ID="Label1" Style="text-align: right; font-size: xx-large; color: #808080"></asp:Label>
Master page code behind: This is where I want to set the text value of the report from the child page.
protected void Page_Load(object sender, EventArgs e)
{
HiddenField hid1 = (HiddenField)MainContent.FindControl("MainContent_hid1");
if (hid1 != null)
{
Label1.Text = hid1.Value;
} }
<input type="hidden" name="ctl00$MainContent$hdnRptTitle" id="MainContent_hdnRptTitle" value="Satellite Availability % Report" />
There is no intellisense for the hdnRptTitle variable.
How can I get this to work? It seems simple enough, but don't know why it not working...
You can add the below code in your MasterPage:
HiddenField hid1 = (HiddenField)MainContent.FindControl("hid1");
if (hid1 != null)
{
Label1.Text = hid1.Value;
}
EDIT: Make sure your Label on the MasterPage is outside your ContentPlaceHolder, as I made this mistake when I first tested.
The above code should work as provided, with your control names, I'm not sure why you are using:
.FindControl("MainContent_hid1");
instead of
.FindControl("hid1");
You can use like this.
There can be multiple conterntPlaceHolder on your master page.
use the id which contains your hidden field in this case I assume that it is ContentPlaceHolder1
HiddenField hid1 = (HiddenField)ContentPlaceHolder1.FindControl("hdnRptTitle");
if (hid1 != null)
{
Label1.Text = hid1.Value;
}
There is a similar post on so
How to access content page controls from master page in asp.net
You can reference a master page and get the control like this:
VB.Net:
Dim te As HiddenField
Dim val As String
te = Me.Page.Master.FindControl("hdnRptTitle")
val = te.Value
c#:
HiddenField te = default(HiddenField);
string val = null;
te = this.Page.Master.FindControl("hdnRptTitle");
val = te.Value;
Why do you think that you can access a control in a content-page of a master-page? A MasterPage is used for multiple pages, why do you want to hardlink it with a specific page, it won't work anymore without it. If the HiddenField is essential for the operation of the master you should declare it there.
For every child page, there is a different rpt title which needs to
show up on the master page. How can I accomplish this?
Then the content page can access it's master to set the text but not vice-versa.
You could provide a public property in the master, e.g.:
public string ReportTitle
{
get { return this.LblReportTitle.Text; }
set { this.LblReportTitle.Text = value; }
}
and in the ContentPage, for example in it's Page_Load:
protected void Page_Load(object sender, EventArgs e)
{
// assuming the type of your master is SiteMaster
var master = this.Master as SiteMaster;
if (master != null)
master.ReportTitle = hdnRptTitle.Value;
}
This approach is still linking the master with one (or multiple) of it's childs, but it would still "work" if the content-page would use a different master-type. You'd also be informed with a compiler error if somebody remove or change the property.
However, where the content stores the report-type or where the master displays it is an implementation detail and can be changed in future without breaking anything.
Read this thread but didn't really answer my question and there were quite a few suggestions so not sure if they are on the right track: Master Page content filtering with respect to asp page
What I have is a site with 1 Master Page and in it is a global footer that all pages use. I want to eliminate the footer on only 1 page (i.e. the login page) but keep all the other master page content intact.
I know I could create a separate Master Page just for this login page but it seems overkill. Is there a way to put in some logic that if it's only this specific page that it would hide the footer and then show on every other page?
Thanks for any tips/suggestions.
Edit: There was already a Page Load sub in the code behind. All I had to add was - MasterPage_Footer.Visible = False on the If statement when users were not logged in and set it to True when they were logged in. Works like a charm. Thanks for all the suggestions.
Expose a property on the MasterPage to allow content pages to override default behavior if needed.
In the MasterPage:
private bool showFooter = true;
public bool ShowFooter { get {return showFooter;} set {showFooter = value;} }
protected void Page_Load(object sender, EventArgs e)
{
footerControl.Visible = showFooter;
}
Make sure content pages that need to access the property have the following line in the aspx:
<%# MasterType TypeName="XXX" %>
and in the content pages code-behind:
protected void Page_Load(object sender, EventArgs e)
{
Master.ShowFooter = false;
}
In your MasterPage:
protected void Page_Load(object sender, EventArgs e)
{
var page = HttpContext.Current.Handler as Page;
FooterControl.Visible = HttpRequest.IsAuthenticated && !(page is LoginPage)
}
HttpContext.Handler Property
is (C# Reference)
My UserControl code is below, I have one TextBox in UserControl and would like to access TextBox.Text property from web page.
UcUserForm user control is inserted in myform.aspx web page.
On myform.aspx PageLoad I set value for textBox like this
ucUserForm.TbFirstName.Text = "Tomas";
Everything works fine. When web page is loaded I see name inside textbox. Then I change value from Tomas to Jonas.
On myform.aspx ButtonClick I am trying to read value
var mynewname = ucUserForm.TbFirstName.Text;
despite that name is changed from Tomas to Jonas in TextBox on web page I still get the old name Tomas. Can't understand where is the problem.
UserControl code behind
public partial class UcUserForm: System.Web.UI.UserControl
{
public TextBox TbFirstName
{
get { return tbFirstName; }
}
}
UserControl web page
<asp:TextBox ID="tbFirstName" autocomplete="off" MaxLength="25" runat="server"></asp:TextBox>
Registration user control code in default.aspx
<%# Register Src="ucUserForm.ascx" TagName="ucUserForm" TagPrefix="uc1" %>
<uc1:ucUserForm ID="ucUserForm" runat="server" />
Try this:
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
ucUserForm.TbFirstName.Text = "Tomas";
}
}
You set it every time you load the page. Try in Init stage.
Similar to this
protected void Page_Init(object sender, EventArgs e)
{
ucUserForm.TbFirstName.Text = "Tomas";
}
The Init just happens once in the Page's life cycle
http://msdn.microsoft.com/en-us/library/ms178472.aspx