Choose Header in ASP.NET Page - c#

I have created a master page (Site.master) which contains the code to display a header, a footer, and a side bar. It works really great, but I am having trouble figuring out how to dynamically choose the header.
Basically, there are two possible header options. If the user is not logged in, I want them to see a login box and links for recovering their password, etc. If they are logged in, they'll see a logout link, and some information about their account (similar to how SO works, actually).
Is it possible to have the Site.master check and use whichever header I want depending on the login status of the user? I'm pretty stuck on where to begin with this (I thought maybe some checks in the code-behind of the master page) so any help would be appreciated.

You should consider using the built-in control, LoginView (MSDN). It is specifically designed to provide multiple templates (views), for authenticated and anonymous users.
This is a best practice approach. You can define your headers/footers etc. for logged in and anonymous users, with appropriate login/logout buttons, user information, etc. etc.
Here's a very basic example:
<asp:LoginView id="LoginView1" runat="server">
<AnonymousTemplate>
<asp:HyperLink ID="lnkLogin" runat="server" NavigateUrl="~/Login.aspx" Text="Login"/>
</AnonymousTemplate>
<LoggedInTemplate>
You are logged in as: <asp:LoginName id="lnCurrentUser" runat="server" />.
</LoggedInTemplate>
</asp:LoginView>
The .NET framework will handle the rest, and display the correct template without any extra code. If you end up using multiple roles in your application you can take this one step further and define templates for these roles as well (administrator vs regular user, etc.)
A perfect solution to your question based on the above: How to: Display Different Information to Anonymous and Logged In Users

Yes, very easily by putting the two possible headers in their own Panel controls and just saying the following in the Page_Load:
if ( Request.IsAuthenticated )
{
// Display
pnlAuthenticated.Visible = true;
pnlGuest.Visible = false;
}
else
{
// Display
pnlAuthenticated.Visible = false;
pnlGuest.Visible = true;
}

Personally I would put each set of header controls into 2 different placeholders and by default set both to invisible
Then with some code in Master Page
PlaceHolder1.Visible = Context.User.IsAuthenticated
PlaceHolder2.Visible = !Context.User.IsAuthenticated

Yes two ways of doing it; embed the header in a panel, and show/hide the panel depending on login status (which occurs in code). Alternatively, you could use two master pages, and do this check in the OnPreInit method (or PreInit event handler) and switch to show which master page you want to use (you can only change master pages programmatically in this event handler).
The problem with the second option is that HttpContext.Current.user may not be available in PreInit...
HTH.

Related

Access web control values

I have two pages in ASP.NET 3.5 and I need to access/read the web controls values from the first page but on the second page. The second page is being displayed with a single link, there is not a post event or something like that.
I guess I should use ViewState but it looks so complicated for this task so please let me know a better way to achieve this.
P.S I'm using C# and Visual Studio 2010
If I understand correctly you have two .aspx pages and you want one page to share information with the other page. Does the first page link to the second page?
I ask because there are a couple of approaches you could take. You could add parameters to a query string in the link to the second page with the information you are trying to send. You could also use the session to temporarily store the information.
For example:
<asp:HyperLink NavigateUrl="www.<yoursite>.com/firstpage.aspx?eggs=1&bacon=yum" Text="Awesome Site" runat="server" />
In the second page you would have this in the codebehind in the Page_Load
string eggs = Request.QueryString["eggs"];
string bacon = Request.QueryString["bacon"];
Now you have the value from page one available in page two.
Another approach might be to use the Session like so:
Page one:
Session["bacon"] = "Yum";
Page two:
string bacon = (string)Session["bacon"];
However, I would advise against overusing session to pass information between pages.
Quick & "Dirty": A session variable which holds the info to pass.
On the first page:
Session["ValueToPassToOtherControl"] = "The value";
On the second page:
var value = Session["ValueToPassToOtherControl"];
Elegant: You need to manage your state in any way (via a static manager whose function is to store and retrieve that info, but that will be also variables). Problem is HTTP is stateless. So you need to bypass this limitation via some kind of storing and retrieving of the data.
You suggested the use of ViewState but forget it, ViewState is the technique used by an ASP.NET Web page to persist changes to the state of a Web Form across postbacks which isn't what's happening on your scenario.
There is a better way that using the QueryString jugglery and Session values.
You could just use the previous page property that is set during cross page posting.
Use an asp link button:
<asp:LinkButton runat="server" id="myLink"
NavigateUrl="~/Page2.aspx"
target="_blank" Text="Go to page 2"></asp:LinkButton>
Then on Page2.aspx.cs:
Get the values from the Page.PreviousPage as follows:
TextBox txtUser = (TextBox)Page.PreviousPage.FindControl("txtUser");
TextBox txtSomeValue = (TextBox)Page.PreviousPage.FindControl("txtSomeValue");
Use these as you require in your second page.

Restricting certain page functionality or user interface to authenticated users in Asp.Net

I am using Asp.Net/C# to build an application.I am using Forms Authentication.I have a requirement such that many of my authenticated (not anonymous) users are restricted to certain page functionalities or user interface.I guess the Login Control could be used for only Authenticated vs Anonymous users.So my question is when I know that certain page component is to be hidden from particular authenticated users , how do I go about it.Do you think I need to use this on the page_load event to hide the components for the pages which have such requirements.
// Is this Tito visiting the page?
string userName = User.Identity.Name;
if (string.Compare(userName, "Tito", true) == 0)
// This is Tito, SHOW the Delete column
FilesGrid.Columns[1].Visible = true;
else
// This is NOT Tito, HIDE the Delete column
FilesGrid.Columns[1].Visible = false;
Are there better approaches to accomplish this.Any help is much appreciated.Thanks
Here you can use the Membeship User class and RolePrincipal to separate the users.
if(HttpContext.Current.User.IsInRole("Level1"))
{
FilesGrid.Columns[1].Visible = true;
}
else
{
FilesGrid.Columns[1].Visible = false;
}
So you make and place your user in different membership names, and then you show them different controls that are depend on the membership role.
Some links:
http://msdn.microsoft.com/en-us/library/ff648345.aspx
http://msdn.microsoft.com/en-us/library/system.web.security.roleprincipal.isinrole.aspx
You also need to know that, when you just hide a control, it's base64 encoded value is still present in the viewstate. The client is able to read it.
The client can also read which hidden control triggers an action. And nothing prevents a "smart" client from triggering this action.
So :
restricted access values should not be bound to the controls, if you don't want to display it (prerender is not called on not visible controls. So doing your binding in prerender is a good habit)
you should always add another access control check inside your event handlers, to see if the call is authorized

Re-using another page section

I have created a web page that I use as a small dashboard to hold issue or no issue. It works great. The page uses an .aspx and .aspx.cs. I would like to be able to reuse the information on this page on other pages. My site already uses master pages and I have not been able to find an easy way to include this information.
How can I use an include from a page that has coding in the code behind easily?
Typically you use Web User Controls for this.
Web User Controls allow you to package up other controls into one that you can drop onto multiple pages. They are great for common UI items such as address entries, dashboards, etc. Basically anything that needs to be the same across multiple pages.
At the risk of seeming very obvious - do you mean usercontrols. These will allow you to reuse chunks of functionality across your site.
I guess this question falls into two categories: User Controls, and Code Reuse. Not sure which one you are after.
User Controls
If you are talking about the controls on your page you will want to create a common user control.
Code Reuse
You need to create a common class (whether it is static or not depends on how you intend to use it) and define functions within that class.
For instance, lets say you have a page that you want to print "Hello World!" on any aspx/.cs page.
You could do this
public static class MyClass
{
public string PrintHelloWorld()
{
return "Hello World!";
}
}
Then you call it from any of your pages like so:
MyClass.PrintHelloWorld();
Right click on the project > Add New Item...
Select User Control (.ascx)
Put your markup & code behind there.
Then you add that control in any other page (includding other controls [although I wouldn't recommend that])
It sounds like you may want to create an ascx User Control.
http://msdn.microsoft.com/en-us/library/ie/2x6sx01c.aspx

how can i authenticate an html control in a .aspx page

how can i authenticate an html control in a .aspx page.
For eg. I have two labels :: lblusername and lblpassowrd, two textboxes to fetch the values from the user and a submit button.
I want all these controls to be of html controls not the asp.net server side controls, authenticate whether the password already exists, check for password string to be ok and on submit give user the home page.
any code help for this.
would also expect some discussion on the events fired, effect on the asp.net page life cycle and some insight about the performance.
Once the HTML controls have the runat="server" attribute, you just use the normal ASP.NET way of authenticating and authorizing.
http://msdn.microsoft.com/en-us/library/ms178329.aspx
http://msdn.microsoft.com/en-us/library/f8kdafb5%28VS.71%29.aspx

Adding a control to a list of Controls dynamically

I have a web page where users need to enter customer contact information. They could enter from 0 to an infinite number of contacts.
I created this page code on page:
<ajaxToolkit:ToolkitScriptManager runat="Server" EnablePartialRendering="true" ID="ScriptManager1" />
<asp:PlaceHolder ID="phCustomerContacts" runat="server" EnableViewState="true">/asp:PlaceHolder>
<asp:LinkButton ID="btnAddContact" runat="server" OnClick="btnAddContact_Click" CssClass="LinkButton" Text="Add Contact"/>
In my code behind I added this:
public void btnAddContact_Click(object sender, EventArgs e)
{
IList<CustomerContactProfile> customerContacts = new List<CustomerContactProfile>();
if (ViewState["CustomerContactList"] != null)
customerContacts = (List<CustomerContactProfile>)ViewState["CustomerContactList"];
CustomerContactProfile contactProfile = (CustomerContactProfile)LoadControl("~/Controls/Embedded/CustomerContactProfile.ascx");
customerContacts.Add(contactProfile);
foreach (CustomerContactProfile contact in customerContacts)
phCustomerContacts.Controls.Add(contact);
ViewState["CustomerContactList"] = customerContacts;
}
This code doesn't work because the ViewState can't handle storing all of that control data. However, I cannot think of another way to store the controls that were already added.
The viewstate of the asp:PlaceHolder control doesn't save anything and I need the controls to be saved so that if a user puts in some data to the first control that the data isn't lost when they add a second one and so on.
Rather than store the entire control, simply store the underlying data in session, and rebuild the control set from that data every time you reload the page.
I'm not sure it's a best way to add contacts dynamically. Wouldn't it be better to create controls via jquery, and send data for creation to web method ?
It would be better to store the number of controls in viewstate to add instead... And then add them in Page Init or PreInit... ViewState would then be retained for each of the dynamic controls. This would be for postbacks after the button click of course.
HTH.
Store the number of controls the user has entered in the view state. Override the LoadViewState page method and add back the number of controls there. The framework will take care of reloading the posted data into the controls for you. You will not lose information. You just have to make sure you add the controls BEFORE the viewstate is restored.
Store it in the Session instead of Viewstate. It's just as bad but it will work!
I think you should not depend on any temporary storage for this -- Viewstate, Session, or otherwise.
You seem to be using your .ascx like I would normally use a class... User control's going to be bigger, though, I imagine, since it has lots of html in it (?).
Anyway, a generic list of a class would be...smaller, at least.
But otherwise, my favorite approach is just to insert each record into a database when it's done (one-by-one) -- at least for manual input, which that's my impression of what you're working with. For example, using a listview, detailsview, gridview, etc.

Categories