天天看點

ASP.NET Core 新增使用者 - ASP.NET Core 基礎教程 - 簡單教程,簡單程式設計ASP.NET Core 新增使用者

原文: ASP.NET Core 新增使用者 - ASP.NET Core 基礎教程 - 簡單教程,簡單程式設計

ASP.NET Core 新增使用者

上一章節我們實作了一個系統資料庫單,但也留了一些東西還沒完成,就是送出系統資料庫單後的動作。使用 Identity 實作注冊功能,但送出系統資料庫單後,需要做的事情很多,比如與 Identity 架構進行互動,以確定使用者有效,告訴 Identity 架構建立該使用者

在本章節,我們将學習如何建立使用者,如何與 Identity 架構進行互動,以確定使用者有效,然後建立該使用者,最後使用注冊的進行登入操作

所有的這些事情,都與

Identity

架構的兩個核心服務: UserManager 和 SignInManager 有關

我們需要将這兩項服務注入我們的控制器

AccountController

,然後才能在建立使用者或登入使用者時調用相應的 API

首先在

AccountController

控制器中添加兩個使用

User

範型的

SignInManager

UserManager

類型的私有變量,然後再建立一個構造函數,用于接收這兩個類型的參數

private SignInManager<User> _signManager;
private UserManager<User> _userManager;

public AccountController(UserManager<User> userManager, SignInManager<User> signManager)
{
    _userManager = userManager;
    _signManager = signManager;
}
      

接下來在使用了

[HttpPost]

特性的

Signup

方法中檢查和驗證送出的資料是否有效,主要是通過檢查

ModelState

是否有效

[HttpPost] 
public async Task<IActionResult> Signup(RegisterViewModel model) { 
   if (ModelState.IsValid) {   
   } 
   return View(); 
}
      

如果

ModelState

有效,則使用

UserName

來建立一個

User

的執行個體,并使用

_userManager

異步儲存使用者名和密碼。

  1. 如果儲存成功,則使用

    _signManager

    直接登入然後跳回首頁
  2. 如果儲存失敗,則告知使用者,并讓使用者輸入正确的資料

内容是不是很多,不過反應到代碼上,就寥寥幾行

[HttpPost] 
public async Task<IActionResult> Signup(RegisterViewModel model) { 
   if (ModelState.IsValid) { 
      var user = new User { UserName = model.Username }; 
      var result = await _userManager.CreateAsync(user, model.Password);

      if (result.Succeeded) { 
         await _signManager.SignInAsync(user, false); 
         return RedirectToAction("Index", "Home"); 
      } else { 
         foreach (var error in result.Errors) { 
            ModelState.AddModelError("", error.Description); 
         } 
      }  
   } 
   return View(); 
} 
      

我們來詳細看看這段代碼

  1. 如果 ModelState 有效,則使用 UserName 來建立一個 User 的執行個體
  2. 但是我們并沒有把密碼和傳遞給

    User

    ,因為

    User

    并沒有屬性來儲存明文密碼,是以我們隻能直接将密碼傳遞給 Identity 架構,架構會自動哈希密碼
  3. 為了使用 Identity 架構儲存使用者資料,我們使用

    UserManager

    的異步方法

    CreateAsync

    ,該方法接收使用者名和明文密碼,然後使用這些資料建立一個新的使用者
  4. 異步方法

    CreateAsync

    會傳回一個結構,告訴我們是成功建立了使用者還是失敗了,如果失敗了,會傳回一些失敗的原因
  5. 如果結果是成功的,就登入剛剛建立帳戶的使用者,且使用 SignInManager 為該使用者簽名,最後将使用者重定向回首頁
  6. 如果結果不成功,則告訴使用者為什麼,将 UserManager 傳回的錯誤結果疊代添加到 ModelState 中。然後視圖中就可以使用标簽助手 ( 如驗證标簽助手 ) 顯示這些錯誤資訊
  7. ModelState.AddModelError

    方法接收一個鍵值對參數,第一個參數為鍵,第二個參數為值,如果鍵是空的,那麼就會把所有錯誤都放在一起
  8. 最後,因為我們使用了異步方法,是以傳回結果必須也是異步的,需要使用

    async Task<IActionResult>

最後,當然了,為了讓程式能正常運作,我們還需要引入三個命名空間

System.ComponentModel.DataAnnotations

System.Threading.Tasks

HelloWorld.Models

,然後删除

AccountController()

空的構造函數

所有這些修改完成後,

AccountController.cs

的代碼如下

using System;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using System.ComponentModel.DataAnnotations;

using HelloWorld.Models;

namespace HelloWorld.Controllers
{
    public class AccountController : Controller
    {

        private SignInManager<User> _signManager;
        private UserManager<User> _userManager;

        public AccountController(UserManager<User> userManager, SignInManager<User> signManager)
        {
            _userManager = userManager;
            _signManager = signManager;
        }



        [HttpGet]
        public ViewResult Signup()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> Signup(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = new User { UserName = model.Username };
                var result = await _userManager.CreateAsync(user, model.Password);

                if (result.Succeeded)
                {
                    await _signManager.SignInAsync(user, false);
                    return RedirectToAction("Index", "Home");
                }
                else
                {
                    foreach (var error in result.Errors)
                    {
                        ModelState.AddModelError("", error.Description);
                    }
                }
            }
            return View();
        }
    }

    public class RegisterViewModel
    {
        [Required, MaxLength(64)]
        public string Username { get; set; }

        [Required, DataType(DataType.Password)]
        public string Password { get; set; }

        [DataType(DataType.Password), Compare(nameof(Password))]
        public string ConfirmPassword { get; set; }
    }
}
      

注冊示範

現在,我們重新開機應用程式,重新整理浏覽器,來到注冊界面,輸入

yufei

aBc123@456

ASP.NET Core 新增使用者 - ASP.NET Core 基礎教程 - 簡單教程,簡單程式設計ASP.NET Core 新增使用者

因為密碼規則必須是 6 個字元以上且包含一個大寫字母和小寫字母,且必須包含一個非數組字母字元,是以如果不是這種格式則會報錯,比如

123

則輸出錯誤如下

ASP.NET Core 新增使用者 - ASP.NET Core 基礎教程 - 簡單教程,簡單程式設計ASP.NET Core 新增使用者

注冊成功後就會跳轉到首頁

ASP.NET Core 新增使用者 - ASP.NET Core 基礎教程 - 簡單教程,簡單程式設計ASP.NET Core 新增使用者

如果使用 SQLite Studio 打開我們的

blogging.db

資料庫,就可以看到我們剛剛建立的使用者

ASP.NET Core 新增使用者 - ASP.NET Core 基礎教程 - 簡單教程,簡單程式設計ASP.NET Core 新增使用者

本章到這裡就已經結束了,我們已經實作了一個相對完整的注冊功能,為啥說是相對完整呢?

  1. 缺少防惡意和機器注冊機制,也就是應該讓輸入手機号和郵箱然後發送驗證碼
  2. 缺少驗證碼,這樣可能導緻頻繁的刷接口注冊
  3. 缺少已登入使用者跳回首頁機制