搜索

查看: 3102|回复: 11

[ASP.NET] ASP.NET MVC使用Identity增删改查用户

[复制链接]
发表于 2023-5-4 11:24:05 | 显示全部楼层 |阅读模式
Editor 2023-5-4 11:24:05 3102 11 看全部
源码在这里:https://github.com/darrenji/UseIdentityCRUDUserInMVC本地下载
在VS2013中创建一个MVC项目,用默认的"无身份验证"作为身份验证机制。
通过控制台下载Bootstrap。
Install-Package -version 3.0.3 bootstrap
下载成功后,在解决方案下的Content和Scripts多了该版本的css和js文件。
把创建项目默认HomeController中的所有Action以及/Views/Home下的所有视图删除。
热热身
先来做一个简单练习。
在HomeController中的Index方法中,把一个字典传递给视图。
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            Dictionary data = new Dictionary();
            data.Add("placeholder", "placeholder");
            return View(data);
        }
    }
_Layout.cshtml设置如下:

   
   
    ASP.NET Identity实战
   
   
   
        .container {padding-top:10px;}
        .validation-summary-errors{color:red;}
   

   
   
        @RenderBody()
   
    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @RenderSection("scripts", required: false)

Home/Index.cshtml视图中:
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
    用户明细
    @foreach (string key in Model.Keys)
        {
            
                @key
                @Model[key]
            
        }

20221022164636911.png

20221022164636911.png


前期准备
分别安装如下组件。
Install-Package Microsoft.AspNet.Identity.EntityFramework –Version 2.0.0
Install-Package Microsoft.AspNet.Identity.OWIN -Version 2.0.0
Install-Package Microsoft.Owin.Host.SystemWeb -Version 2.1.0

配置Web.config如下:


  
   
   
  
  
   
  
   
   
   
   
   
  
  
   
   
  
  
   
      
        
        
      
      
        
        
      
      
        
        
      
      
        
        
      
      
        
        
      
   
  
  
   
   
      
   
  
以上,
  • 增加了connectionStrings节点,将自动创建localdb数据库
  • 在appSettings节点中增加了一个key为owin:AppStartup项,这是确保OWIN运行正常的全局配置
    在Models文件夹下创建如下类。
        public class AppUser : IdentityUser
        {
        }
    在解决方案下创建Infrastructure文件夹。
    在Infrastructure文件夹下创建一个上下文类,需要实现IdentityDbContext接口。
       public class AppIdentityDbContext : IdentityDbContext
        {
            public AppIdentityDbContext()
                : base("IdentityDb")
            {
            }
            static AppIdentityDbContext()
            {
                //使用EF Code First第一次创建的时候调用
                Database.SetInitializer(new IdentityDbInit());
            }
            public static AppIdentityDbContext Create()
            {
                return new AppIdentityDbContext();
            }
        }
        //初始化
        public class IdentityDbInit : DropCreateDatabaseIfModelChanges
        {
            protected override void Seed(AppIdentityDbContext context)
            {
                PerformInitialSetup(context);
                base.Seed(context);
            }
            //初始化工作
            public void PerformInitialSetup(AppIdentityDbContext context)
            { }
        }
    在Infrastructure文件夹下创建一个管理用户的类,需要继承UserManager类。
    还记得,先前在appSettings节点中配置了一个如下方式:

    OWIN需要一个全局启动文件,默认会到项目的顶级命名空间下找IdentityConfig这个类。
    那就在App_Start中创建IdentityConfig这个类,这个类在WebApplication4这个命名空间下。
    namespace WebApplication4
    {
        public class IdentityConfig
        {
            public void Configuration(IAppBuilder app)
            {
                app.CreatePerOwinContext(AppIdentityDbContext.Create);
                app.CreatePerOwinContext(AppUserManager.Create);
                app.UseCookieAuthentication(new CookieAuthenticationOptions {
                    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                    LoginPath = new Microsoft.Owin.PathString("/Account/Login")
                });
            }
        }
    }
    显示用户
    创建AdminController,现在可以向视图传递所有的用户了,编写如下:
        public class AdminController : Controller
        {
            public ActionResult Index()
            {
                return View(UserManager.Users);
            }
            private AppUserManager UserManager
            {
                get
                {
                    return HttpContext.GetOwinContext().GetUserManager();
                }
            }
        }
    再创建Admin/Index.cshtml类型为IEnumerable的强类型视图。
    @model IEnumerable
    @{
        ViewBag.Title = "Index";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
       
            所有用户账户
       
        @if (Model.Count() == 0)
            {
                }
            else
            {
                foreach (WebApplication4.Models.AppUser user in Model)
                {
                    }
            }
    IDNameEmail
    还没有创建用户
    @user.Id@user.UserName@user.Email
                            @using (Html.BeginForm("Delete", "Admin",
                                new { id = user.Id }))
                            {
                                @Html.ActionLink("编辑", "Edit", new { id = user.Id },
                                        new { @class = "btn btn-primary btn-xs" })
                               
                                    删除
                               

                            }
                        

    @Html.ActionLink("创建用户", "Create", null, new { @class = "btn btn-primary" })

    20221022164636912.png

    20221022164636912.png


    创建用户
    在Models文件夹下创建一个视图模型。
    namespace WebApplication4.Models
    {
        public class CreateModel
        {
            public string Id { get; set; }
            [Required]
            public string Name { get; set; }
            [Required]
            public string Email { get; set; }
            [Required]
            public string Password { get; set; }
        }
    }
    在AdminController中添加创建用户相关的方法。
       public class AdminController : Controller
        {
            public ActionResult Index()
            {
                return View(UserManager.Users);
            }
            //创建显示
            public ActionResult Create()
            {
                return View();
            }
            [HttpPost]
            public async Task Create(CreateModel model)
            {
                if(ModelState.IsValid)
                {
                    var user = new AppUser{UserName = model.Name, Email = model.Email};
                    IdentityResult result = await UserManager.CreateAsync(user, model.Password);
                    if(result.Succeeded)
                    {
                        return RedirectToAction("Index");
                    }else{
                        AddErrorsFromResult(result);
                    }
                }
                return View(model);
            }
            //创建接收
            private void AddErrorsFromResult(IdentityResult result)
            {
                foreach(var error in result.Errors)
                {
                    ModelState.AddModelError("", error);
                }
            }
            private AppUserManager UserManager
            {
                get
                {
                    return HttpContext.GetOwinContext().GetUserManager();
                }
            }
        }
    在Admin/Create.cshtml视图页中:
    @model WebApplication4.Models.CreateModel
    @{
        ViewBag.Title = "Create";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    Create
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
       
       
            创建用户
            
            @Html.ValidationSummary(true)
            
                @Html.LabelFor(model => model.Name, new { @class = "control-label col-md-2" })
                
                    @Html.EditorFor(model => model.Name)
                    @Html.ValidationMessageFor(model => model.Name)
                
            
            
                @Html.LabelFor(model => model.Email, new { @class = "control-label col-md-2" })
                
                    @Html.EditorFor(model => model.Email)
                    @Html.ValidationMessageFor(model => model.Email)
                
            
            
                @Html.LabelFor(model => model.Password, new { @class = "control-label col-md-2" })
                
                    @Html.EditorFor(model => model.Password)
                    @Html.ValidationMessageFor(model => model.Password)
                
            
            
                
                   
                
            
       
    }
        @Html.ActionLink("返回", "Index")

    20221022164636913.png

    20221022164636913.png


    点击"创建"按钮,创建成功返回显示用户页面。

    20221022164636914.png

    20221022164636914.png


    oh, my god,只是配置了一下就有数据了? 数据在哪呢?
    点击左上角的"服务器资源管理器",右键"IdentityDb",点击"刷新"。

    20221022164636915.png

    20221022164636915.png


    再打开AspNetUsers表,刚创建的用户赫然在列。

    20221022164636916.png

    20221022164636916.png


    好像还有点欠缺,用户输入密码的时候,总应该有些限制吧。
    能想到的,ASP.NET Identity都为我们准备好了。有一个PasswordValidator类就是干这个的。
    在Infrastructure文件夹中创建一个PasswordValidator类的继承子类。
    namespace WebApplication4.Infrastructure
    {
        public class CustomPasswordValidator : PasswordValidator
        {
            public override async Task[I] ValidateAsync(string pass)
            {
                IdentityResult result = await base.ValidateAsync(pass);
                if (pass.Contains("12345"))
                {
                    var errors = result.Errors.ToList();
                    errors.Add("密码中包含太多连续数字");
                    result = new IdentityResult(errors);
                }
                return result;
            }
        }
    }
    然后需要把这个规则告诉UserManager。
    namespace WebApplication4.Infrastructure
    {
        public class AppUserManager : UserManager
        {
            public AppUserManager(IUserStore store) : base(store) { }
            public static AppUserManager Create(IdentityFactoryOptions options, IOwinContext context)
            {
                //identity ef上下文
                AppIdentityDbContext db = context.Get();
                //与identity ef相关的UserStore
                IUserStore us = new UserStore(db);
                AppUserManager manager = new AppUserManager(us);
                //密码相关
                manager.PasswordValidator = new CustomPasswordValidator {
                    RequiredLength = 6,
                    RequireNonLetterOrDigit = false,
                    RequireDigit = false,
                    RequireLowercase = true,
                    RequireUppercase = true
                };
                return manager;
            }
        }
    }
    再次运行程序,创建用户页面,尝试输入不通过的密码。

    20221022164636917.png

    20221022164636917.png


    不过,关于密码的规则,似乎可以在View Model的验证层面就可以解决掉。
    编辑和删除用户
    在AdminController中增加编辑和删除的部分。
        public class AdminController : Controller
        {
            public ActionResult Index()
            {
                return View(UserManager.Users);
            }
            //创建显示
            public ActionResult Create()
            {
                return View();
            }
            //创建接收
            [HttpPost]
            public async Task Create(CreateModel model)
            {
                if(ModelState.IsValid)
                {
                    var user = new AppUser{UserName = model.Name, Email = model.Email};
                    IdentityResult result = await UserManager.CreateAsync(user, model.Password);
                    if(result.Succeeded)
                    {
                        return RedirectToAction("Index");
                    }else{
                        AddErrorsFromResult(result);
                    }
                }
                return View(model);
            }
            //编辑显示
            public async Task Edit(string id)
            {
                AppUser user = await UserManager.FindByIdAsync(id);
                
                if(User != null)
                {
                    CreateModel createModel = new CreateModel();
                    createModel.Id = user.Id;
                    createModel.Email = user.Email;
                    createModel.Name = user.UserName;
                    createModel.Password = user.PasswordHash;
                    return View(createModel);
                }
                else
                {
                    return RedirectToAction("Index");
                }
            }
            //接收编辑
            [HttpPost]
            public async Task Edit(CreateModel createModel)
            {
                
                if(ModelState.IsValid)
                {
                    AppUser user = await UserManager.FindByIdAsync(createModel.Id);
                    if (user != null)
                    {
                        //关于邮箱
                        user.Email = createModel.Email;
                        IdentityResult validEmail = await UserManager.UserValidator.ValidateAsync(user);
                        if (!validEmail.Succeeded)
                        {
                            AddErrorsFromResult(validEmail);
                        }
                        user.UserName = createModel.Name;
                        //关于密码
                        IdentityResult validPass = null;
                        if (createModel.Password != string.Empty)
                        {
                            validPass = await UserManager.PasswordValidator.ValidateAsync(createModel.Password);
                            if (validPass.Succeeded)
                            {
                                user.PasswordHash = UserManager.PasswordHasher.HashPassword(createModel.Password);
                            }
                            else
                            {
                                AddErrorsFromResult(validPass);
                            }
                        }
                        user.Email = createModel.Email;
                        //验证结果
                        if ((validEmail.Succeeded && validPass == null) || (validEmail.Succeeded
        && createModel.Password != string.Empty && validPass.Succeeded))
                        {
                            IdentityResult result = await UserManager.UpdateAsync(user);
                            if (result.Succeeded)
                            {
                                return RedirectToAction("Index");
                            }
                            else
                            {
                                AddErrorsFromResult(result);
                            }
                        }
                        else
                        {
                            ModelState.AddModelError("", "无此用户");
                        }
                    }
                    return View(createModel);
                }
                else
                {
                    return View(createModel);
                }
                
            }
            //删除
            [HttpPost]
            public async Task Delete(string id)
            {
                AppUser user = await UserManager.FindByIdAsync(id);
                if(user != null)
                {
                    IdentityResult result = await UserManager.DeleteAsync(user);
                    if(result.Succeeded)
                    {
                        return RedirectToAction("Index");
                    }
                    else
                    {
                        return View("Error", result.Errors);
                    }
                }
                else
                {
                    return View("Error", new string[] { "没有此用户" });
                }
            }
            private void AddErrorsFromResult(IdentityResult result)
            {
                foreach(var error in result.Errors)
                {
                    ModelState.AddModelError("", error);
                }
            }
            private AppUserManager UserManager
            {
                get
                {
                    return HttpContext.GetOwinContext().GetUserManager();
                }
            }
        }
    Admin/Edit.cshtml视图。
    @model WebApplication4.Models.CreateModel
    @{
        ViewBag.Title = "Edit";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    Edit
    @using (Html.BeginForm())
    {
        @Html.AntiForgeryToken()
       
       
            
            @Html.ValidationSummary(true)
            @Html.HiddenFor(model => model.Id)
            
                @Html.LabelFor(model => model.Name, new { @class = "control-label col-md-2" })
                
                    @Html.EditorFor(model => model.Name)
                    @Html.ValidationMessageFor(model => model.Name)
                
            
            
                @Html.LabelFor(model => model.Email, new { @class = "control-label col-md-2" })
                
                    @Html.EditorFor(model => model.Email)
                    @Html.ValidationMessageFor(model => model.Email)
                
            
            
                @Html.LabelFor(model => model.Password, new { @class = "control-label col-md-2" })
                
                    @Html.EditorFor(model => model.Password)
                    @Html.ValidationMessageFor(model => model.Password)
                
            
            
                
                   
                
            
       
    }
        @Html.ActionLink("返回", "Index")
    另外,如果删除失败,跳转到Shared/Error.cshtml视图页。
    @model IEnumerable
    @{ ViewBag.Title = "Error";}
        @switch (Model.Count())
        {
            case 0:
                @: Something went wrong. Please try again
                break;
            case 1:
            @Model.First();
                              break;
            default:
            @: 发现如下错误:
            
                @foreach (string error in Model)
                {
                   
  • @error
                }
            

                break;
        }
    @Html.ActionLink("确定", "Index", null, new { @class = "btn btn-default" })
    至此,使用ASP.NET Identy实现对用户的增删改查完毕,ASP.NET Identity真的很好很强大!
    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对知鸟论坛的支持。如果你想了解更多相关内容请查看下面相关链接
  • 回复

    使用道具 举报

    发表于 2023-6-29 15:19:43 | 显示全部楼层
    麻辣鸡翅 2023-6-29 15:19:43 看全部
    这个帖子不回对不起自己!我想我是一天也不能离开知鸟论坛
    回复

    使用道具 举报

    发表于 2023-6-29 19:55:08 | 显示全部楼层
    123456819 2023-6-29 19:55:08 看全部
    我看不错噢 谢谢楼主!知鸟论坛越来越好!
    回复

    使用道具 举报

    发表于 2023-6-30 00:44:52 | 显示全部楼层
    向往草原403 2023-6-30 00:44:52 看全部
    这个帖子不回对不起自己!我想我是一天也不能离开知鸟论坛
    回复

    使用道具 举报

    发表于 2023-6-30 09:43:26 | 显示全部楼层
    十二音阶囤 2023-6-30 09:43:26 看全部
    既然你诚信诚意的推荐了,那我就勉为其难的看看吧!知鸟论坛不走平凡路。
    回复

    使用道具 举报

    发表于 2023-6-30 21:45:29 | 显示全部楼层
    胡37 2023-6-30 21:45:29 看全部
    这东西我收了!谢谢楼主!知鸟论坛真好!
    回复

    使用道具 举报

    发表于 2023-7-3 21:13:26 | 显示全部楼层
    462710480 2023-7-3 21:13:26 看全部
    论坛不能没有像楼主这样的人才啊!我会一直支持知鸟论坛
    回复

    使用道具 举报

    发表于 2023-7-4 01:41:43 | 显示全部楼层
    123456868 2023-7-4 01:41:43 看全部
    我看不错噢 谢谢楼主!知鸟论坛越来越好!
    回复

    使用道具 举报

    发表于 2023-7-4 05:11:25 | 显示全部楼层
    贰十岁装成熟装s 2023-7-4 05:11:25 看全部
    这东西我收了!谢谢楼主!知鸟论坛真好!
    回复

    使用道具 举报

    发表于 2023-7-4 06:09:43 | 显示全部楼层
    术数古籍专卖疤 2023-7-4 06:09:43 看全部
    其实我一直觉得楼主的品味不错!呵呵!知鸟论坛太棒了!
    回复

    使用道具 举报

    • 您可能感兴趣
    点击右侧快捷回复 【请勿灌水】
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则 返回列表

    RSS订阅| SiteMap| 小黑屋| 知鸟论坛
    联系邮箱E-mail:zniao@foxmail.com
    快速回复 返回顶部 返回列表