In this article I will explain with an example, how to show and hide Edit Button in GridView based on Role in ASP.Net using C# and VB.Net.
The Role Based Security will be implemented using Form Authentication in ASP.Net using C# and VB.Net.
Once the User logs in, his Role will be determined and if the User belongs to the Administrator role then he will be able to see the Edit Button in GridView and if the User does not belong to Administrator role the Edit Button will be hidden in GridView.
Database
I have made use of the following tables with the schema as follows.
Users
Roles
The Roles table has two Roles i.e. Administrator and User.
Customers
I have made use of the following table Customers with the schema as follows to populate the GridView.
I have already inserted few records in the table.
Note: You can download the database table SQL by clicking the download link below.
Login Page
This page will be used for allowing users login into the site. I have used the same code and design as used in the article
Simple User Login Form example in ASP.Net with little modifications for implementing roles.
HTML Markup
The HTML markup consists of an ASP.Net Login control for which the OnAuthenticate event handler has been specified.
<asp:Login ID = "Login1" runat = "server" OnAuthenticate= "ValidateUser"></asp:Login>
Namespaces
You will need to import the following namespaces.
C#
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
using System.Web.Security;
VB.Net
Imports System.Data
Imports System.Configuration
Imports System.Data.SqlClient
Imports System.Web.Security
Stored Procedure to Validate the User Credentials and get the Role
The following stored procedure is used to validate the user credentials and it also gets the assigned role, this stored procedure first checks whether the username and password are correct else returns -1.
If the username and password are correct but the user has not been activated then the code returned is -2.
If the username and password are correct and the user account has been activated then UserId and the Role is returned by the stored procedure.
CREATE PROCEDURE [dbo].[Validate_User]
@Username NVARCHAR(20),
@Password NVARCHAR(20)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @UserId INT, @LastLoginDate DATETIME, @RoleId INT
SELECT @UserId = UserId, @LastLoginDate = LastLoginDate, @RoleId = RoleId
FROM Users WHERE Username = @Username AND [Password] = @Password
IF @UserId IS NOT NULL
BEGIN
IF NOT EXISTS(SELECT UserId FROM UserActivation WHERE UserId = @UserId)
BEGIN
UPDATE Users
SET LastLoginDate = GETDATE()
WHERE UserId = @UserId
SELECT @UserId [UserId],
(SELECT RoleName FROM Roles
WHERE RoleId = @RoleId) [Roles] -- User Valid
END
ELSE
BEGIN
SELECT -2 [UserId], '' [Roles]-- User not activated.
END
END
ELSE
BEGIN
SELECT -1 [UserId], '' [Roles] -- User invalid.
END
END
Validating the User Credentials and determining the Role
The below event handler gets called when the Log In button is clicked. Here the Username and Password entered by the user is passed to the stored procedure and if the authentication is successful the UserId and the Role is returned.
The returned UserId and Role is used to create a FormsAuthentication ticket and the user is redirected either to the default page specified in the Web.Config or to the URL specified in the ReturnUrl QueryString parameter.
C#
protected void ValidateUser(object sender, EventArgs e)
{
int userId = 0;
string roles = string.Empty;
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand("Validate_User"))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@Username", Login1.UserName);
cmd.Parameters.AddWithValue("@Password", Login1.Password);
cmd.Connection = con;
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
reader.Read();
userId = Convert.ToInt32(reader["UserId"]);
roles = reader["Roles"].ToString();
con.Close();
}
switch (userId)
{
case -1:
Login1.FailureText = "Username and/or password is incorrect.";
break;
case -2:
Login1.FailureText = "Account has not been activated.";
break;
default:
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, Login1.UserName, DateTime.Now, DateTime.Now.AddMinutes(2880), Login1.RememberMeSet, roles, FormsAuthentication.FormsCookiePath);
string hash = FormsAuthentication.Encrypt(ticket);
HttpCookie cookie = new HttpCookie(FormsAuthentication.FormsCookieName, hash);
if (ticket.IsPersistent)
{
cookie.Expires = ticket.Expiration;
}
Response.Cookies.Add(cookie);
Response.Redirect(FormsAuthentication.GetRedirectUrl(Login1.UserName, Login1.RememberMeSet));
break;
}
}
}
VB.Net
Protected Sub ValidateUser(sender As Object, e As EventArgs)
Dim userId As Integer = 0
Dim roles As String = String.Empty
Dim constr As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
Using con As New SqlConnection(constr)
Using cmd As New SqlCommand("Validate_User")
cmd.CommandType = CommandType.StoredProcedure
cmd.Parameters.AddWithValue("@Username", Login1.UserName)
cmd.Parameters.AddWithValue("@Password", Login1.Password)
cmd.Connection = con
con.Open()
Dim reader As SqlDataReader = cmd.ExecuteReader()
reader.Read()
userId = Convert.ToInt32(reader("UserId"))
roles = reader("Roles").ToString()
con.Close()
End Using
Select Case userId
Case -1
Login1.FailureText = "Username and/or password is incorrect."
Exit Select
Case -2
Login1.FailureText = "Account has not been activated."
Exit Select
Case Else
Dim ticket As New FormsAuthenticationTicket(1, Login1.UserName, DateTime.Now, DateTime.Now.AddMinutes(2880), Login1.RememberMeSet, roles, _
FormsAuthentication.FormsCookiePath)
Dim hash As String = FormsAuthentication.Encrypt(ticket)
Dim cookie As New HttpCookie(FormsAuthentication.FormsCookieName, hash)
If ticket.IsPersistent Then
cookie.Expires = ticket.Expiration
End If
Response.Cookies.Add(cookie)
Response.Redirect(FormsAuthentication.GetRedirectUrl(Login1.UserName, Login1.RememberMeSet))
Exit Select
End Select
End Using
End Sub
Inside Application_AuthenticateRequest event of the Global.asax file, the Roles are fetched from the FormsAuthentication Ticket and assigned to the HttpContext User object. This way the Role is available throughout the Application through the Context.
C#
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
if (HttpContext.Current.User != null)
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
if (HttpContext.Current.User.Identity is FormsIdentity)
{
FormsIdentity id = (FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
string userData = ticket.UserData;
string[] roles = userData.Split(',');
HttpContext.Current.User = new GenericPrincipal(id, roles);
}
}
}
}
VB.Net
Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs)
If HttpContext.Current.User IsNot Nothing Then
If HttpContext.Current.User.Identity.IsAuthenticated Then
If TypeOf HttpContext.Current.User.Identity Is FormsIdentity Then
Dim id As FormsIdentity = DirectCast(HttpContext.Current.User.Identity, FormsIdentity)
Dim ticket As FormsAuthenticationTicket = id.Ticket
Dim userData As String = ticket.UserData
Dim roles As String() = userData.Split(","c)
HttpContext.Current.User = New GenericPrincipal(id, roles)
End If
End If
End If
End Sub
Show Hide Edit Button in GridView based on Role in ASP.Net
HTML Markup
The HTML Markup consists of an ASP.Net GridView with three BoundField columns and a TemplateField column consisting of the Edit Button.
<asp:GridView ID="gvCustomers" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="CustomerId" HeaderText="Customer Id" />
<asp:BoundField DataField="Name" HeaderText="Name" />
<asp:BoundField DataField="Country" HeaderText="Country" />
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnEdit" Text="Edit" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Once the user logs in, a check is performed whether User is logged in or not. If the User is not logged in, he is redirected back to the Login page.
Then the GridView is populated using the records from the Customers Table.
The 4th Column of the GridView i.e. the Column which consists of the Edit Button is show only when the logged in User belongs to the Administrator Role.
C#
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
if (!this.Page.User.Identity.IsAuthenticated)
{
Response.Redirect("~/Login.aspx");
}
gvCustomers.DataSource = GetData("SELECT * FROM Customers");
gvCustomers.DataBind();
//Show the Edit Column only to Administrators.
gvCustomers.Columns[3].Visible = this.Page.User.IsInRole("Administrator");
}
}
private DataTable GetData(string query)
{
string constr = ConfigurationManager.ConnectionStrings["constr"].ConnectionString;
using (SqlConnection con = new SqlConnection(constr))
{
using (SqlCommand cmd = new SqlCommand(query))
{
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
{
DataTable dt = new DataTable();
sda.Fill(dt);
return dt;
}
}
}
}
VB.Net
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Not Me.IsPostBack Then
If Not Me.Page.User.Identity.IsAuthenticated Then
Response.Redirect("~/Login.aspx")
End If
gvCustomers.DataSource = GetData("SELECT * FROM Customers")
gvCustomers.DataBind()
'Show the Edit Column only to Administrators.
gvCustomers.Columns(3).Visible = Me.Page.User.IsInRole("Administrator")
End If
End Sub
Private Function GetData(query As String) As DataTable
Dim constr As String = ConfigurationManager.ConnectionStrings("constr").ConnectionString
Using con As New SqlConnection(constr)
Using cmd As New SqlCommand(query)
cmd.CommandType = CommandType.Text
cmd.Connection = con
Using sda As New SqlDataAdapter(cmd)
Dim dt As New DataTable()
sda.Fill(dt)
Return dt
End Using
End Using
End Using
End Function
Screenshots
GridView showing Edit Button for Administrator Role
GridView not showing Edit Button for Normal Role
Downloads