ASP. NET MVC5 website development user registration (4), mvc5 website development
1. Changes to the default Web project
Users do this part by themselves, so they delete the automatically generated user-related code.
2. Add a Member Region
Right-click a web project and choose add region Member.
Add the Home controller and select MVC5 controller-Null
We add a View to the public ActionResult Index (). The code is simple, that is, the user name is displayed.
@ {ViewBag. Title = "member center" ;}< h2> welcome! @ User. Identity. Name
Let's run it first. An error occurred.
This is because the project has two controllers named Home, And the namespace must be added to the route. First open the MemberAreaRegistration in the region and add the namespace.
Open RouteConfig in the project and add a namespace.
Refresh the browser to display it normally.
Then add the user controller UserController.
Iii. model changes
Here, we first modify the User model of the Models project. It was originally considered that each User can only belong to one User group. Later, we carefully considered it, which is not appropriate. For example, one User can also serve multiple roles, therefore, the relationship between users and user groups is changed to one-to-many.
- User model. Delete the GroupID in the model and the foreign key Group.
- Role model. In the past, UserGroup (User Group) was changed to a role. Considering permission management, roles are more appropriate than user groups. In addition, roles have a wider meaning, which can be user groups or positions, it can also be a department ...... The modified code is as follows:
Using System. componentModel. dataAnnotations; namespace Ninesky. models {/// <summary> /// role /// <remarks> /// create: 2014.02.02 // modify: 2014.02.16 // </remarks> /// </summary> public class Role {[Key] public int RoleID {get; set ;} /// <summary> /// name /// </summary> [Required (ErrorMessage = "Required")] [StringLength (20, MinimumLength = 2, errorMessage = "{1} to {0} characters")] [Display (Name = "Name")] public string Name {get; set ;} /// <summary> /// role type <br/> // 0 (Common registered user), 1 (VIP type ), 3 Management (permission management type) /// </summary> [Required (ErrorMessage = "Required")] [Display (Name = "user group type")] public int Type {get; set ;}/// <summary> /// description /// </summary> [Required (ErrorMessage = "Required")] [StringLength (50, ErrorMessage = "less than {0} characters")] [Display (Name = "Description")] public string Description {get; set ;} /// <summary> /// obtain the role Type name /// </summary> /// <returns> </returns> public string TypeToString () {switch (Type) {case 0: return "normal"; case 1: return "Privilege"; case 2: return "management"; default: return "unknown ";}}}}
UserRoleRelation class. Add the role relation class UserRoleRelation in the Models project. Code:
Using System. componentModel. dataAnnotations; namespace Ninesky. models {/// <summary> /// User Role Relationship /// <remarks> /// create: 2014.02.16 // </remarks> /// </summary> public class UserRoleRelation {[Key] public int RelationID {get; set ;} /// <summary >/// user ID /// </summary> [Required ()] public int UserID {get; set ;} /// <summary >/// role ID /// </summary> [Required ()] public int RoelID {get; set ;}}}
NineskyDbContext class. For example, if the blue box is the modified part, the red box is newly added.
3. Verification Code and Sha256 Encryption
1. Verification Code
The verification code is a required function for a website. I divide the verification code into three parts: create verification code characters, generate images based on the verification code, save the verification code in the User controller action, and return images.
Create a verification code character CreateVerificationText ()
Add the Security class to Common and use the pseudo-random number generator to generate the verification code string in the class.
/// <Summary> /// create a verification code character /// </summary> /// <param name = "length"> length </param> /// <returns> Verification Code character </returns> public static string CreateVerificationText (int length) {char [] _ verification = new char [length]; char [] _ dictionary = {'A', 'B', 'C', 'D', 'E ', 'F', 'G', 'h', 'I', 'J', 'k', 'l', 'M', 'n', 'O ', 'P', 'Q', 'R','s ', 't', 'U', 'V', 'w', 'x', 'y ', 'Z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'h', 'I ', 'J', 'k', 'l', 'M', 'n', 'O', 'P', 'Q', 'R','s ', 'T', 'U', 'V', 'w', 'x', 'y', 'z', '0', '1', '2 ', '3', '4', '5', '6', '7', '8', '9'}; Random _ random = new Random (); for (int I = 0; I <length; I ++) {_ verification [I] = _ dictionary [_ random. next (_ dictionary. length-1)];} return new string (_ verification );}
Generate an image CreateVerificationImage () based on the verification code ()
The idea is to use GDI + to create a canvas, use the pseudo-random number generator to generate a gradient Paint Brush, and then create a gradient text.
/// <Summary> /// create a verification code image /// </summary> /// <param name = "verificationText"> Verification code string </param> /// <param name = "width"> image width </param> /// <param name = "height"> image length </param> /// <returns> image </returns> public static Bitmap CreateVerificationImage (string verificationText, int width, int height) {Pen _ pen = new Pen (Color. black); Font _ font = new Font ("Arial", 14, FontStyle. bold); Brush _ brush = null; Bitmap _ bitmap = new Bitmap (width, height); Graphics _ g = Graphics. fromImage (_ bitmap); SizeF _ totalSizeF = _ g. measureString (verificationText, _ font); SizeF _ curCharSizeF; PointF _ startPointF = new PointF (width-_ totalSizeF. width)/2, (height-_ totalSizeF. height)/2); // Random number generator random _ Random = new Random (); _ g. clear (Color. white); for (int I = 0; I <verificationText. length; I ++) {_ brush = new LinearGradientBrush (new Point (), new Point (), Color. fromArgb (_ random. next (255), _ random. next (255), _ random. next (255), Color. fromArgb (_ random. next (255), _ random. next (255), _ random. next (255); _ g. drawString (verificationText [I]. toString (), _ font, _ brush, _ startPointF); _ curCharSizeF = _ g. measureString (verificationText [I]. toString (), _ font); _ startPointF. X + = _ curCharSizeF. width;} _ g. dispose (); return _ bitmap ;}
The User controller action saves the verification code and returns an image.
First, add the User controller, and add the Controller UserController in the Member area. Write a VerificationCode method in the controller. The process is: In the method, we first create a 6-digit verification code string-> Use CreateVerificationImage to create a verification code image-> write the image to OutputStream-> write the verification code string to TempData.
Difference between stored in TempData and Session: TempData is transmitted only once, that is, after being passed to the next action, the action code will be destroyed after execution, and the Session will be continuously saved, therefore, it is more appropriate to use TempData for verification codes.
/// <Summary> /// Verification Code /// </summary> /// <returns> </returns> public ActionResult VerificationCode () {string verificationCode = Security. createVerificationText (6); Bitmap _ img = Security. createVerificationImage (verificationCode, 160, 30); _ img. save (Response. outputStream, System. drawing. imaging. imageFormat. jpeg); TempData ["VerificationCode"] = verificationCode. toUpper (); return null ;}
Let's take a look at the effect of generating the image verification code:
2. Sha256 Encryption
Add the static method Sha256 (string plainText) to the Security class of the COmmon project)
/// <Summary> /// 256-bit hash encryption /// </summary> /// <param name = "plainText"> plainText </param> /// <returns> ciphertext </returns> public static string Sha256 (string plainText) {SHA256Managed _ sha256 = new SHA256Managed (); byte [] _ cipherText = _ sha256.ComputeHash (Encoding. default. getBytes (plainText); return Convert. toBase64String (_ cipherText );}
Iv. Registration
Add the registered view model to Ninesky. Web. Areas. Member. Models.
Using System. componentModel. dataAnnotations; namespace Ninesky. web. areas. member. models {public class RegisterViewModel {// <summary> /// user name // </summary> [Required (ErrorMessage = "Required")] [StringLength (20, minimumLength = 4, ErrorMessage = "{2} to {1} characters")] [Display (Name = "UserName")] public string UserName {get; set ;} /// <summary> /// display name /// </summary> [Required (ErrorMessage = "Required")] [StringLength (20, MinimumLength = 2, errorMessage = "{2} to {1} characters")] [Display (Name = "Display Name")] public string DisplayName {get; set ;} /// <summary> /// password /// </summary> [Required (ErrorMessage = "Required")] [Display (Name = "password")] [StringLength (20, MinimumLength = 6, ErrorMessage = "{2} to {1} characters")] [DataType (DataType. password)] public string Password {get; set ;} /// <summary> /// confirm the Password /// </summary> [Required (ErrorMessage = "Required")] [Compare ("Password ", errorMessage = "inconsistent passwords entered twice")] [Display (Name = "Confirm Password")] [DataType (DataType. password)] public string ConfirmPassword {get; set ;}/// <summary> // email /// </summary> [Required (ErrorMessage = "Required")] [Display (Name = "email")] [DataType (DataType. emailAddress, ErrorMessage = "Incorrect Email format")] public string Email {get; set ;} /// <summary> /// Verification Code /// </summary> [Required (ErrorMessage = "Required")] [StringLength (6, MinimumLength = 6, errorMessage = "Incorrect verification code")] [Display (Name = "Verification Code")] public string VerificationCode {get; set ;}}}
Add Register () action to UserController and return the RegisterViewModel view.
/// <Summary> /// Register /// </summary> /// <returns> </returns> public ActionResult Register () {return View ();}
View
@ Model Ninesky. Web. Areas. Member. Models. RegisterViewModel @ {ViewBag. Title = "register"; Layout = "~ /Views/Shared/_ Layout. cshtml ";}@ using (Html. beginForm () {@ Html. antiForgeryToken () <div class = "form-horizontal">
Add public ActionResult Register (RegisterViewModel register) to the user controller to process registration data submitted by the user.
[HttpPost] [ValidateAntiForgeryToken] public ActionResult Register (RegisterViewModel register) {if (TempData ["VerificationCode"] = null | TempData ["VerificationCode"]. ToString ()! = Register. verificationCode. toUpper () {ModelState. addModelError ("VerificationCode", "Incorrect verification code"); return View (register);} if (ModelState. isValid) {if (userService. exist (register. userName) ModelState. addModelError ("UserName", "UserName already exists"); else {User _ user = new User () {UserName = register. userName, // The Default User Group Code is written here DisplayName = register. displayName, Password = Security. sha256 (register. password), // email Verification Certificate and Email uniqueness problem Email = register. email, // user Status issue Status = 0, RegistrationTime = System. dateTime. now}; _ user = userService. add (_ user); if (_ user. userID> 0) {return Content ("registered successfully! "); // AuthenticationManager. SignIn ();} else {ModelState. AddModelError (" "," registration failed! ") ;}} Return View (register );}
In the Code, many root user settings are not taken into consideration first, and will be modified later when the user settings are implemented. If the registration fails, the view is returned and an error is displayed. If the registration is successful, the view registration is successful. You can log on directly after the user registration is completed. Check the effect.
Click "register". The registration is successful.
A simple user registration is completed, including the verification code, sha256 encryption, registration view model, and verification of user data submission and storage. The user registration is followed. The registration will use ClaimsIdentity and HttpContext. GetOwinContext (). Authentication. SignIn ();