Asp.NET 多层登陆实现代码

本文将详细讲解如何利用 Asp.NET 实现多层登陆,以下是完整的实现攻略:

第一步:创建用户数据库

在创建用户数据库之前,必须先安装 Microsoft SQL Server 数据库并创建一个新的数据库。可以按照以下步骤创建一个新的用户数据库:

  1. 打开 Microsoft SQL Server 的管理工具(如SqlServer Management Studio或Visual Studio)并登录
  2. 在 "Object Explorer" 窗口中,右键单击 "Databases" 文件夹,并选择 "New Database"
  3. 在 "New Database" 对话框中,输入一个数据库名称,例如 "Users",并点击 "OK" 按钮
  4. 在左侧导航栏中,展开新创建的 "Users" 数据库,右键单击 "Tables" 文件夹,并选择 "New Table"
  5. 添加一个 "Users" 表格,包括以下字段:
  6. Id:int类型,自增主键
  7. UserName:nvarchar(50),用于存放用户名
  8. Password:nvarchar(50),用于存放加密后的密码
  9. Role:nvarchar(50),用于存放用户角色
  10. 保存并关闭 "New Table" 对话框
  11. 在 "Users" 表格中,添加至少一个用户,用于后续测试验证登陆功能

第二步:创建 Asp.NET 应用程序

  1. 打开 Visual Studio,建立一个新的 Asp.NET 项目。选择类型为 "Web Application",并选择 "Empty" 模板
  2. 将项目命名为 "AspNetMultyLayerLogin"
  3. 在解决方案资源管理器中,右键单击 "AspNetMultyLayerLogin" 项目,并选择 "Add" -> "New Folder"
  4. 将新创建的文件夹命名为 "Models"
  5. 在 "Models" 文件夹中,创建一个名为 "User" 的新类,并定义以下属性:
public class User
{
    public int Id { get; set; }
    public string UserName { get; set; }
    public string Password { get; set; }
    public string Role { get; set; }
}
  1. 在 "Models" 文件夹中,创建一个名为 "UserDataAccessLayer" 的新类,并定义以下方法:
public class UserDataAccessLayer
{
    private static string connectionString = ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString;

    public static User GetUser(string userName, string password)
    {
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            connection.Open();
            SqlCommand command = new SqlCommand("SELECT * FROM Users WHERE UserName = @UserName AND Password = @Password", connection);
            command.Parameters.AddWithValue("@UserName", userName);
            command.Parameters.AddWithValue("@Password", password);
            SqlDataReader reader = command.ExecuteReader();
            if (reader.HasRows)
            {
                User user = new User();
                while (reader.Read())
                {
                    user.Id = int.Parse(reader["Id"].ToString());
                    user.UserName = reader["UserName"].ToString();
                    user.Password = reader["Password"].ToString();
                    user.Role = reader["Role"].ToString();
                }
                return user;
            }
            else
            {
                return null;
            }
        }
    }
}
  1. 在 "Models" 文件夹中,创建一个名为 "RoleProvider" 的新类,并定义以下方法:
public class RoleProvider
{
    public static bool IsUserInRole(string userName, string role)
    {
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            connection.Open();
            SqlCommand command = new SqlCommand("SELECT Role FROM Users WHERE UserName = @UserName", connection);
            command.Parameters.AddWithValue("@UserName", userName);
            SqlDataReader reader = command.ExecuteReader();
            if (reader.HasRows)
            {
                while (reader.Read())
                {
                    string userRole = reader["Role"].ToString();
                    if (userRole.Equals(role, StringComparison.OrdinalIgnoreCase))
                    {
                        return true;
                    }
                }
            }
            return false;
        }
    }
}
  1. 在 "Models" 文件夹中,创建一个名为 "Utils" 的新类,并定义以下方法:
public class Utils
{
    private static Random random = new Random();

    public static string GenerateSalt(int length)
    {
        const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        return new string(Enumerable.Repeat(chars, length).Select(s => s[random.Next(s.Length)]).ToArray());
    }

    public static string ComputeHash(string plainText, string salt)
    {
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
        byte[] saltBytes = Encoding.UTF8.GetBytes(salt);
        byte[] plainTextWithSaltBytes = new byte[plainTextBytes.Length + saltBytes.Length];
        for (int i = 0; i < plainTextBytes.Length; i++)
        {
            plainTextWithSaltBytes[i] = plainTextBytes[i];
        }
        for (int i = 0; i < saltBytes.Length; i++)
        {
            plainTextWithSaltBytes[plainTextBytes.Length + i] = saltBytes[i];
        }
        HashAlgorithm algorithm = new SHA256Managed();
        byte[] hash = algorithm.ComputeHash(plainTextWithSaltBytes);
        return Convert.ToBase64String(hash);
    }
}
  1. 在 "Models" 文件夹中,创建一个名为 "LoginViewModel" 的新类,并定义以下属性:
public class LoginViewModel
{
    public string UserName { get; set; }
    public string Password { get; set; }
    public string Role { get; set; }
    public bool RememberMe { get; set; }
}
  1. 在 "Models" 文件夹中,创建一个名为 "AccountController" 的新控制器,并使用以下代码替换默认的代码:
public class AccountController : Controller
{
    [AllowAnonymous]
    public ActionResult Login(string returnUrl)
    {
        ViewBag.ReturnUrl = returnUrl;
        return View();
    }

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public ActionResult Login(LoginViewModel model, string returnUrl)
    {
        if (ModelState.IsValid)
        {
            string salt = Utils.GenerateSalt(16);
            string hashedPassword = Utils.ComputeHash(model.Password, salt);
            User user = UserDataAccessLayer.GetUser(model.UserName, hashedPassword);
            if (user != null)
            {
                FormsAuthentication.SetAuthCookie(user.UserName, model.RememberMe);
                if (RoleProvider.IsUserInRole(user.UserName, model.Role))
                {
                    return RedirectToLocal(returnUrl);
                }
                else
                {
                    ModelState.AddModelError("", "You are not authorized to access this page");
                }
            }
            else
            {
                ModelState.AddModelError("", "Invalid username or password");
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult LogOff()
    {
        FormsAuthentication.SignOut();
        return RedirectToAction("Index", "Home");
    }

    private ActionResult RedirectToLocal(string returnUrl)
    {
        if (Url.IsLocalUrl(returnUrl))
        {
            return Redirect(returnUrl);
        }
        else
        {
            return RedirectToAction("Index", "Home");
        }
    }
}
  1. 在解决方案资源管理器中,右键单击 "AspNetMultyLayerLogin" 项目,并选择 "Add" -> "New Folder"
  2. 将新创建的文件夹命名为 "Views"
  3. 在 "Views" 文件夹中,创建一个名为 "Account" 的新文件夹
  4. 在 "Account" 文件夹中,创建一个名为 "Login.cshtml" 的新视图,并使用以下代码替换默认的代码:
@model AspNetMultyLayerLogin.Models.LoginViewModel
@{
    ViewBag.Title = "Log in";
}

<h2>@ViewBag.Title</h2>

@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) 
{
    @Html.AntiForgeryToken()

    <div class="form-group">
        @Html.LabelFor(m => m.UserName, new { @class = "control-label" })
        @Html.TextBoxFor(m => m.UserName, new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.UserName)
    </div>

    <div class="form-group">
        @Html.LabelFor(m => m.Password, new { @class = "control-label" })
        @Html.PasswordFor(m => m.Password, new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.Password)
    </div>

    <div class="form-group">
        @Html.LabelFor(m => m.Role, new { @class = "control-label" })
        @Html.DropDownListFor(m => m.Role, new SelectList(new List<string> { "Admin", "User" }), "-- Select Role --", new { @class = "form-control" })
        @Html.ValidationMessageFor(m => m.Role)
    </div>

    <div class="form-group">
        @Html.CheckBoxFor(m => m.RememberMe)
        @Html.LabelFor(m => m.RememberMe, new { @class = "control-label" })
    </div>

    <div class="form-group">
        <input type="submit" value="Log in" class="btn btn-primary" />
    </div>
}

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

第三步:测试并部署应用程序

  1. 运行应用程序并转到登录页面
  2. 输入先前在用户数据库中创建的用户来进行登录
  3. 以不同的角色尝试登录,应该会被授权或拒绝访问所请求的资源。

以上就是完整的 Asp.NET 多层登陆实现攻略。通过此方法,可以轻松实现多层登陆,并对不同用户进行授权或拒绝访问不同的页面。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Asp.NET 多层登陆实现代码 - Python技术站

(0)
上一篇 2023年5月31日
下一篇 2023年5月31日

相关文章

  • C#中WinForm程序退出方法技巧总结

    C#中WinForm程序退出方法技巧总结 在C#中,WinForm是一种常见的GUI编程技术,它可以用于开发各种类型的桌面应用程序。在WinForm程序中,退出程序是一个常见的需求。以下是一些WinForm程序退出方法技巧的总结: 1. 使用Application.Exit方法 可以使用Application.Exit方法退出WinForm程序。以下是一个示…

    C# 2023年5月15日
    00
  • C#中Invoke 和 BeginInvoke 的真正涵义

    下面是详细的讲解“C#中Invoke和BeginInvoke的真正涵义”的攻略。 Invoke和BeginInvoke的概述 在C#中,Invoke和BeginInvoke是两个常用的方法,用于在UI线程上执行操作。它们的主要目的是“跨线程访问UI控件”,因为在Windows Forms、WPF、ASP.NET Web Forms等应用程序中,只能在创建UI…

    C# 2023年6月7日
    00
  • Unity实现移动物体到鼠标点击位置

    为了实现将物体移动到鼠标点击位置,我们需要用到Unity中的以下两个组件:Input和Transform。 Input组件用于检测用户的鼠标点击事件,而Transform组件则用于移动物体。 首先,在Unity的场景中创建一个3D物体,然后将它的Transform组件设置为可编辑。 然后,在物体的脚本中添加以下代码,用于检测鼠标点击事件,并将物体移动到鼠标所…

    C# 2023年6月3日
    00
  • C#序列化与反序列化实例

    让我来为你详细讲解C#序列化与反序列化实例的完整攻略。 什么是C#序列化与反序列化? C#序列化与反序列化是指将C#的对象序列化成二进制字节流,并将其存储在磁盘或通过网络发送到其他计算机,同时,反序列化是指反过来将二进制字节流反序列化为C#对象。这样做的好处是可以方便地将对象跨平台传输和存储。 如何实现C#序列化与反序列化? C#提供了两种序列化方式:二进制…

    C# 2023年6月1日
    00
  • C#使用Selenium的实现代码

    以下是关于使用C#和Selenium的完整攻略。 简介 Selenium是一个广泛用于Web应用程序测试的框架。使用Selenium的原因是可以模拟用户的操作,如单击、输入、选择等,并且可以轻松地与不同的Web浏览器集成。C#和Selenium之间的结合提供了访问Web应用的完整范围,这些应用在自动化测试、爬虫和其他领域都有很多用途。 安装Selenium …

    C# 2023年5月31日
    00
  • C#实现飞行棋项目

    C#实现飞行棋项目攻略 项目概述 飞行棋是一种经典的游戏,玩家需要掷骰子,并根据骰子的点数控制棋子移动,最终到达终点获得胜利。在本项目中,我们将实现一个可以在Windows电脑上运行的飞行棋游戏,并且支持单人和双人模式。 准备工作 在开始编码之前,我们需要安装一些必要的工具和组件。首先是Visual Studio,建议安装最新版的Visual Studio …

    C# 2023年6月6日
    00
  • C#往线程里传递参数的方法小结

    针对“C#往线程里传递参数的方法小结”,我将分以下几步来进行详细讲解: 一、参数传递的基本方法 在C#中,向Thread线程传递参数有多种方法。其中最常用的一种是通过将参数封装到一个对象中,再将该对象传递给Thread.Start()方法。这个对象可以是任何一个类的实例,常用的方式是使用匿名类型或者是Tuple类型。 具体来说,可以按照如下方式编写代码: i…

    C# 2023年6月7日
    00
  • C# Environment.GetCommandLineArgs()方法: 获取当前应用程序的命令行参数

    Environment.GetCommandLineArgs() 方法简介 Environment.GetCommandLineArgs() 方法返回当前进程的命令行参数。命令行参数是启动进程时指定的字符串数组,例如,从命令行或通过使用Process.Start 方法启动进程时,可以传递命令行参数,这些参数将通过Environment.GetCommandL…

    C# 2023年4月19日
    00
合作推广
合作推广
分享本页
返回顶部