Checking if a user is logged in from site master file - c#

When users log in, their sessions are set like so:
HttpContext.Current.Session["LoggedIn"] = true;
HttpContext.Current.Session["FullName"] = (string)Reader["FirstName"] + " " + (string)Reader["LastName"];
My Site.master file contains a navigation menu that's site-wide, and I'd like to change it to show different links depending on if the user is logged in or not.
Something like this in Site.master:
<div id="navigation">
<ul>
<%
if (HttpContext.Current.Session["LoggedIn"] != null)
{
%><li>Log out</li><%
}
else
{
%>
<li>Register</li>
<li>Log in</li>
<%
}
%>
</ul>
</div>
However, this doesn't seem to work. Looks like you can't use ASP tags like PHP tags.
How can I achieve this?

Seems like you are more in to PHP,For starters I recommend you go for the normal .NET process
1.Write HTML in aspx page,replace HTML 'a' with asp:linkbutton ,likr
<div id="navigation">
<ul>
<li><asp:LinkButton ID="LinkButton2" runat="server" PostBackUrl="/user74/aspnet/Logout.aspx">Log out</asp:LinkButton></li>
</ul>
</div>
2.Write codes in pagename.aspx.cs page,in your case write session checks in page_load event
protected void Page_Load(object sender, EventArgs e)
{
if (HttpContext.Current.Session["LoggedIn"] != null)
{
LinkButton1.Visible = true;
}
}

In the first place, I would advice you to use ASP.NET Authentication to authenticate the users instead of using Session. This gives numerous benefits such as Role based security etc.
You can authenticate the users against
Windows (default)
Forms
Passport
Once you use one of these authentication methods, you can use the LoginView control to render different HTML for different set of users. For more information you can see ASP.NET Tip: Using the LoginView Control

Related

Roles and User management in asp.net webforms using code behind

Issue: Using roles that I have created in my database, I want to be able to limit use for specific users depending on that users role.
Information: I am not using an MVC approach, only empty .aspx pages that I have wired up through to my database to show information etc. Provided are images of tables that are holding the role/user information in my database Roles , Users , Role/User. Ideally I want to remove items from my menu depending on which role the user is in. So lets say the user is in the role "Worker" they will only see 2 menu "controls" or "buttons" on the aspx page menu.
Attempted solution: On the landing page after a user has logged in, the Page_Load method checks to see which role the user is in and sends them to the appropriate page. The issue with this solution is that I have to create duplicates for every page depending on which role the user is in.
Question: How can I edit the HTML in a aspx webform using the c# code behind.
Question 2: Is there a simple solution to limit use depending on a user's role without have a ton of duplicate aspx pages.
Please let me know if there is more information needed.
The menu is created in the HTML on the aspx form like this:
<ul id="centered">
<li><a href='Welcome.aspx'><span>Home</span></a></li>
<li class='active has-sub'>
<a href='#'><span>Sales</span></a>
<ul>
<li class="active has-sub">
<a href='#'><span>Sales</span></a>
<ul>
<li><a href='Sales.aspx'><span>Create</span></a></li>
<li><a href='Sales.aspx'><span>View</span></a></li>
</ul>
</li>
</ul>
</li>
You need to mark you menu ul to runat="server" and give it a unique id.
<ul id="centered">
<li><a href='Welcome.aspx'><span>Home</span></a></li>
<li class='active has-sub'>
<a href='#'><span>Sales</span></a>
<ul>
<li class="active has-sub">
<a href='#'><span>Sales</span></a>
<ul runat="server" id="ul_menu">
<li><a href='Sales.aspx'><span>Create</span></a></li>
<li><a href='Sales.aspx'><span>View</span></a></li>
</ul>
</li>
</ul>
</li>
</ul>
Here I have change to <ul runat="server" id="ul_menu">
Now you can use this id ul_menu and add item to this from code behind on the basis of role of the user. for example --
protected void Page_Load(object sender, EventArgs e)
{
PopulateMenu();
}
private void PopulateMenu()
{
string role = "B";//You can get the role of logged in user from membeship
StringBuilder txt = new StringBuilder();
if (role == "A")
{
txt.Append("<li><a href='Sales.aspx'><span>Create</span></a></li>");
}
if (role == "B")
{
txt.Append("<li><a href='Sales.aspx'><span>View</span></a></li>");
}
ul_menu.InnerHtml = txt.ToString();
}

post form data to another page without __VIEWSTATE variable in query string

Currently I am working on Payment gateway integration with my ASP.NET application, in which I have to post few form variables to Payment Gateway page using GET method. When I do it using simple HTML page using form controls to hold the values and post it to external payment gateway page then everything is working fine.
When I am trying to do it from inside of my ASP.NET c# application, I am getting error "Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that configuration specifies the same validationKey and validation algorithm. AutoGenerate cannot be used in a cluster.". On checking the Query string which is getting posted to external payment gateway page from my asp.net c# page there is an additional __VIEWSTATE variable appended to my desired query string which holds the variable values I want to post to the payment gateway page.
I have made EnableViewState="false" EnableEventValidation="false" EnableViewStateMac="false" to <%Page%> directives in ASPX page and added "this.EnableViewState = false" in overridden onLoad method in code behind.
For your reference adding the code snippets below:
ASPX page
<body>
<%--<form id="pgform" name="pgform" action="http://xxx.xx.xx.xx:xxxx/_layouts/Portal/EWallet_BillDesk_Dummy.aspx" method="post" runat="server"> --%>
<form id="pgform" name="pgform" action="http://xxx.xxx.xx.xx:xxxx/PaymentGateway.aspx"
method="get" target="_blank" runat="server">
<asp:HiddenField ID="mid" runat="server"></asp:HiddenField>
<asp:HiddenField ID="mtrxid" runat="server"></asp:HiddenField>
<asp:HiddenField ID="mitem" runat="server"></asp:HiddenField>
<asp:HiddenField ID="amount" runat="server"></asp:HiddenField>
<script type="text/javascript">
document.pgform.submit();
//alert("connector fired");
</script>
</form>
</body>
code behind
protected override void OnLoad(EventArgs e)
{
this.EnableViewState = false;
base.OnLoad(e);
}
protected void Page_Load(object sender, EventArgs e)
{
byte[] EncrKeyStream = Encoding.UTF8.GetBytes("nlxcK}~MWgf1WxrT");
if (Request.QueryString["c"] != null)
{
string qry = ConvertHexToString(Request.QueryString["c"]);
string strApplicationNo = qry.Split('|')[0];
string strTxnAmount = "1";//qry.Split('|')[1];
string mtrxId = "ABCMI" + strApplicationNo;
string mItem = "MOTOR INSURANCE";
string encmtrxId = EncryptDecrypt.Encrypt(mtrxId, EncrKeyStream);
string encmItem = EncryptDecrypt.Encrypt(mItem, EncrKeyStream);
string encAmount = EncryptDecrypt.Encrypt(strTxnAmount, EncrKeyStream); ;
mid.Value = "ABC_DEV";
mtrxid.Value = encmtrxId;
mitem.Value = encmItem;
amount.Value = encAmount;
}
}
Please help me in this regard. I really need this solution now it's been quite few hours & I am unable to find one solution. Requesting your help.
Thanks in advance.
Don't use <form runat="server" /> or server-side controls. Use a standard <form> and normal <input> fields (all without runat="server") instead. That way ASP.NET won't generate view state or other hidden fields on your behalf, and you can submit the form cross-host.
I also caution you to have a security expert audit your code and your use of cryptography.

best practices for dynamic content

I have a pretty extensive Classic ASP background (using server-side javascript), and my company is finally (FINALLY) making the push towards recoding everything in ASP.Net (using C#). I have a good grasp on good programming practices in Classic ASP and I usually try to make sure I code things the "right" way. I've been reading ASP.Net tutorials and feel like I have a pretty understanding of the basics. I have good discipline about separating client side javascript into external js files, keeping styling outside of the markup in external css files, etc. So, when reading these novice tutorials I understand the concept of the code-behind pages. It makes sense to me to separate the c# code from what will ultimately become the markup for the page. Making < asp:button > objects and the code-behind rules to alter them makes perfect sense.
However, I'm having a hard time wrapping my head around how to do something simple like I would have done in Classic ASP like this:
<%
if (condition) {
%>
<input type="button" value="click me" onclick="dosomething()" />
<%
}
else {
%>
<span>You don't have permission to see the button</span>
<%
}
%>
I'm having a hard time trying to figure out how I'm supposed to fit the conditional stuff you see above into the code-behind page. If I was showing a button under both circumstances, I'd make an <asp:button> object and style it in the code-behind page accordingly - but in the example above I'm only showing the button if the condition is true, and a span block if false.
I know that you don't HAVE to put ALL the c# code in the code-behind page. I can use the <% %> tags the same way I would do in Classic ASP. But, if I do that then it seems to me that it lessens the relevance of the code-behind page. For example, I know you can use an external css stylesheet to stylize your page and at the same time use inline styles on individual tags as well. I believe this to be poor practice, however. It makes it difficult to later have to adjust the styles on that element if you don't know whether to look in the markup or in the css file to find the relevant styles affecting that element.
It seems to me that the same would hold true for your markup and code-behind pages. Is it just a necessary evil to have to mix the 2, or is there a better way to do what I'm demonstrating above?
You could have in your markup:
<asp:Button .. Visible="False" />
<asp:Label .. Text="You do not have permissions" Visible="False" />
Note the Visible property. ASP.NET web forms is build on the idea of an object model, so the button and label are objects you can work with. In the code behind, you can have:
protected void Page_Load(object sender, EventArgs e) {
.
.
if (Xcondition = true) {
Button1.visible= true;
Label2.Visible = false;
}
else {
Button1.visible= false;
Label2.Visible = true;
}
}
Is the traditional way to accomplish this. You just have to figure out where in the lifecycle you need to do this, as load may not be the best (Init or PreRender event, for instance). If you only need to do this at startup once, do if (!Page.IsPostBack) { .. } to ensure it only runs once.
I made a small example that you can basically just copy/paste and mess around with a little.
This is the aspx code:
< body>
<form id="form1" runat="server">
<div>
<asp:TextBox runat="server" ID="txtCondition"></asp:TextBox>
<asp:Button runat="server" Text="Check condition" ID="btnCheckCondition" OnClick="btnCheckCondition_Click" />
<asp:Button runat="server" Text="Click me" ID="btnSubmit" OnClick="btnSubmit_Click" Visible="false"/>
<asp:Label runat="server" ID="lblMsg"></asp:Label>
</div>
</form>
</body>
this is the code behind: (if you double click on the btnCheckCondition, the click_event method will be automatically generated in your codebehind.
protected void btnCheckCondition_Click(object sender, EventArgs e)
{
if (txtCondition.Text == "Show the button")
{
btnSubmit.Visible = true;
lblMsg.Text = "You are allowed to see the button.";
}
else
{
lblMsg.Text = "You are NOT allowed to see the button.";
}
}
This will basically check the input in the textbox txtCondition. If it is equal to "Show the button", the second button will become visible. If the text is something else, the button will not appear and a label will say that you are not allowed to see the button.
have a label and a button in the page. check the condition from code behind and based on the condition, hide or show the control. you can use visibility attribute of the controls to hide or show them. Also use asp.net controls so that you can access them from code behind.
Unless you have a good reason not to, use the Visible property. (In ASP.NET Web Forms, you're asking for trouble if you change the structure of the component tree dynamically other than using repeater controls.) What I do is:
Page.aspx
<button type='button' Visible='<%# condition %>' runat='server'>
Click Me!
</button>
<span Visible='<%# !condition %>' runat='server'>
No button for you!
</span>
Page.aspx.cs
protected void Page_Load() {
if (!IsPostBack) DataBind(); // evaluates <%# ... %> expressions
}
(My preference is to make controls to "pull" data from code-behind instead of pushing it there, and use anonymous and plain HTML controls over their heavier equivalents when possible.) Any way of setting Visible before the page renders will work though.
First to help you with the easy way, to been able the condition to been recognized you need to define it and make it public on code behind. For example:
<%if (condition) {%>
<input type="button" value="click me" onclick="dosomething()" />
<%}else { %>
<span>You don't have permission to see the button</span>
<% } %>
and on code behind
public partial class OnePage : System.Web.UI.Page
{
public bool condition = false;
protected void Page_Load(object sender, EventArgs e)
{
// here change the condition
}
}
Second case with function call
<%if (fCheckAuth()) {%>
<input type="button" value="click me" onclick="dosomething()" />
<%}else { %>
<span>You don't have permission to see the button</span>
<% } %>
and on code behind
public partial class OnePage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
public bool fCheckAuth()
{
// return your evaluate
return false;
}
}
More asp.net form style
Now, working with the new asp.net (compared with the classic asp) you can also do that (and similar to that).
<asp:Panel runat="server" ID="pnlShowA">
<input type="button" value="click me" onclick="dosomething()" />
</asp:Panel>
<asp:Panel runat="server" ID="pnlShowB">
<span>You don't have permission to see the button</span>
</asp:Panel>
Use one asp:Panel to warp your full content, and on code behind you open it and close it.
public partial class OnePage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (condition)
{
pnlShowA.Visible = true;
pnlShowB.Visible = false;
}
else
{
pnlShowA.Visible = false;
pnlShowB.Visible = true;
}
}
}
While the question is not about using ASP.NET Web Forms versus ASP.Net MVC. I felt compelled to point out that it may be more beneficial going with ASP.NET MVC rather than ASP.NET Web Forms in your scenario.
I say this because Classic ASP and ASP.NET MVC inline style is similar. In most cases you could probably convert ASP (<% %>) to Razor(a different flavor of in-lining server-side code with HTML) with little modification to the underlining logic. I don't know about you but the less code I have to write the better. For example, your above code would convert to the following Razor syntax:
#if (condition) {
<input type="button" value="click me" onclick="dosomething()" />
}
else {
<span>You don't have permission to see the button</span>
}
To answer your question, I would disable the button on the server-side. Have a disabled on the client. In the case the button is disabled, enable the Label with the appropriate text.
//Code-behind
bool correctPermission = true;
submit.Enabled = correctPermission;
noPermissionMessage.Enabled = !correctPermission;
//Client Code
<asp:Button ID="submit" runat="server" Text="Click Me" />
<asp:Label ID="noPermissionMessage" runat="server" Text="You don't have permission to see the button" Enabled="false" />

How to check the existance of a value from asp designer page?

I'm getting a list of string from db like:
AddCustomer,
AddUser,
ListCustomer,
ListUser
These are the prefix of asp pages.
I need to hide and show certain pages in the page. Following is the html snippet:
<li>Customer Management
<ul>
<%if (AddCustomer) //how to check whether my string is present or not, is it possible?
{ %><li>Add Customer</li><%} %>
<li>List Customer</li>
</ul>
</li>
Have you tried writing method then calling it from aspx page?
<%# YourMethodName((string)Eval("AddCustomer")) %>

How to customize the user control for only one page of the ASP.NET website?

I have two user controls (ascx); one contains some forms, and the other one contains the menu bar.
I used both of them in many pages. Now, I need to customize the one that has the menu bar for the Admin Homepage. So, is it possible to add some changes to the user control just for this page.
I mean by changes, adding two elements to the menu bar.
For instance, let us assume that the two pages are called: Admin, Settings. How will you customize the user control for them?
My code for the Menu User Control (ascx file):
<div class="topnav">
<ul class="menu" runat="server" >
<li>Home</li>
<li>Sub-Menu1
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ul>
</li>
<li>Sub-Menu2
<ul>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item </li>
<li>Item</li>
<li>Item</li>
</ul>
</li>
<li>ITEM</li>
<li>About</li>
<li>Contact Us</li>
<li>Help</li>
<li class="menuItem1ToHide">Admin</li>
</ul>
<div class="clr"></div>
</div>
And inside the Master Page, I put:
<uc1:MenuBar ID="MenuBar1" runat="server" />
As you see from above code, I added the Admin page as the last element in the list, and the code-behind class, I added the bool method mentioned below, but I don't know how to make the last element only visible for the Admin rather than the other users
By the way, I am using the ASP.NET Role-Based Security since I am using the Windows Authentication. This to define the Admin from the Normal User.
Sure,
Add the two items to the menu bar, and hide them for everything but the admin page. You can do that in several ways; check the URL of the current request, or add a property to the user control (default the menu items to false).
public bool DisplayAdminOnlyMenuItems
{
get { return menuItem1ToHide.Visible; }
set
{
menuItem1ToHide.Visible = value;
menuItem2ToHide.Visible = value;
}
}
or you can use a method to do it. The property allows you to set it in markup or code. For instance, if your UC definition was this:
<uc:Menu ID="ucMenu" runat="server" />
You can set it, for the admin page, this way:
<uc:Menu ID="ucMenu" runat="server" DisplayAdminOnlyMenuItems="True" />
And then it will make those menu items visible.
EDIT: In your case, since everything is role security, add runat="server" to the LI to show or hide:
<li id="liAdmin" runat="server" class="menuItem1ToHide">Admin</li>
In your code, on prerender of the user control, do:
protected override void OnPreRender(EventArgs e)
{
liAdmin.Visible = this.User.IsInRole("Admin");
//if visible isn't available, use style["display"] = (this.User.IsInRole("Admin") ? "" : "none";
}
Something like that.
You could check the url in the Page_Load of the ascx and do the alterations there
Add the new elements to the user control and expose a property (say bool ShowAdminMenuItems) in the control. Show/hide the new elements based on this property's value. Set this property as true in the page where you need these two menu items to show up. Rest of the pages don't know about it, so they would not set it and the default value (false) would be in affect.
Yes, you can render some elements conditionally by doing:
<% if( somecondition) { %>
<li class="yourclass"> text here </li>
<%}%>

Categories

Resources