现在网站基本都用手机注册,很少用邮箱注册,本篇内容比较多,代码我会尽量加备注,有些操作需要连续添加几个文件才不报错,如果VS显示错误,请继续后续步骤。

前面已经有一篇文章讲到集成短信发送模块:http://www.cnblogs.com/shensigzs/category/1147235.html

在此基础上才能做手机注册功能,没有完成的同学请先去整合后再回来。

语言文件

AbpZeroTemplate-zh-CN.xml文件末尾添加如下键值对:

文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Core\Localization\AbpZeroTemplate\AbpZeroTemplate-zh-CN.xml

<text name="MobileRegister" value="手机注册" />
<text name="OccupiedMobilePhone" value="手机号码已注册或被占用" />
<text name="MobilePhone" value="手机号码" />

添加模型文件

在Web项目下Models\Account目录下添加MobileRegisterViewModel.cs,代码如下:

文件路径:D:\abpweb\PddSellerAssistant\PddSellerAssistant.Web\Models\Account\MobileRegisterViewModel.cs

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
using Abp.Auditing;
using MyCompanyName.AbpZeroTemplate.Authorization.Users;
using MyCompanyName.AbpZeroTemplate.Security;
using MyCompanyName.AbpZeroTemplate.Validation;
using MyCompanyName.AbpZeroTemplate.MultiTenancy;namespace MyCompanyName.AbpZeroTemplate.Web.Models.Account
{public class MobileRegisterViewModel : IValidatableObject{[StringLength(Tenant.MaxTenancyNameLength)]public string TenancyName { get; set; }/// <summary>/// 手机号码/// </summary>
        [Required][StringLength(User.MaxMobilePhoneLength)]public string MobilePhone { get; set; }/// <summary>/// 手机验证码/// </summary>
        [Required][StringLength(User.MobileCodeLength)]public string MobilePhoneCode { get; set; }[StringLength(User.MaxPlainPasswordLength)][DisableAuditing]public string Password { get; set; }public PasswordComplexitySetting PasswordComplexitySetting { get; set; }public IEnumerable<ValidationResult> Validate(ValidationContext validationContext){if (!string.IsNullOrWhiteSpace(MobilePhone)){if (new ValidationHelper().IsPhoneNumber(MobilePhone) == false){yield return new ValidationResult("您输入的手机号码无效 !");}}else{yield return new ValidationResult("手机号码不能为空 !");}}}
}

Core项目

User.cs类添加如下代码:

文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Core\Authorization\Users\User.cs

public const int MaxMobilePhoneLength = 11;
public const int MobileCodeLength = 6;

再打开ValidationHelper.cs,添加如下代码:

文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Core\Validation\ValidationHelper.cs

/// <summary>/// 验证手机号是否有效/// </summary>/// <param name="phoneNumber"></param>/// <returns></returns>public bool IsPhoneNumber(string phoneNumber){if (string.IsNullOrWhiteSpace(phoneNumber)){return false;}string pattern = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\d{8}$";return Regex.IsMatch(phoneNumber, pattern);}

UserStore.cs类添加如下代码:

文件路径:D:\abpweb\PddSellerAssistant\PddSellerAssistant.Core\Authorization\Users\UserStore.cs

private readonly IRepository<User, long> _userRepository;
private readonly IUnitOfWorkManager _unitOfWorkManager;

 _userRepository = userRepository;
_unitOfWorkManager = unitOfWorkManager;

#region 扩展方法/// <summary>/// 按手机号码查询用户/// </summary>/// <param name="phoneNumber"></param>/// <returns></returns>public virtual async Task<User> FindByPhoneNumberAsync(string phoneNumber){return await _userRepository.FirstOrDefaultAsync(user => user.PhoneNumber == phoneNumber);}[UnitOfWork]public virtual async Task<User> FindByPhoneNumberAsync(int? tenantId, string phoneNumber){using (_unitOfWorkManager.Current.SetTenantId(tenantId)){return await FindByPhoneNumberAsync(phoneNumber);}}#endregion

AbpZeroTemplateConsts.cs添加如下代码:

文件路径:D:\abpweb\PddSellerAssistant\PddSellerAssistant.Core\AbpZeroTemplateConsts.cs

#region 手机短信模板/// <summary>/// 手机短信验证码通用模板/// </summary>public const string SmsTemplateCommonCode = "SMS_119088461";#endregion

UserManager.cs 重写CreateAsync、CheckDuplicateUsernameOrEmailAddressAsync方法,代码如下:

文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Core\Authorization\Users\UserManager.cs

public override async Task<IdentityResult> CreateAsync(User user){var result = await CheckDuplicateUsernameOrEmailAddressAsync(user.Id, user.UserName, user.EmailAddress);if (!result.Succeeded){return result;}if (string.IsNullOrWhiteSpace(user.EmailAddress)){user.EmailAddress = string.Empty;}var tenantId = GetCurrentTenantId();if (tenantId.HasValue && !user.TenantId.HasValue){user.TenantId = tenantId.Value;}try{return await base.CreateAsync(user);}catch (Exception e){Console.WriteLine(e);throw;}}public override async Task<IdentityResult> CheckDuplicateUsernameOrEmailAddressAsync(long? expectedUserId, string userName, string emailAddress){var user = (await FindByNameAsync(userName));if (user != null && user.Id != expectedUserId){return AbpIdentityResult.Failed(string.Format(L("Identity.DuplicateName"), userName));}return IdentityResult.Success;}private int? GetCurrentTenantId(){if (_unitOfWorkManager.Current != null){return _unitOfWorkManager.Current.GetTenantId();}return AbpSession.TenantId;}private string L(string name){return LocalizationManager.GetString(AbpZeroConsts.LocalizationSourceName, name);}

Application项目

MyAbpLoginResultType.cs添加这个类,代码如下:

文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Application\Authorization\MyAbpLoginResultType.cs

namespace MyCompanyName.AbpZeroTemplate.Authorization
{public enum MyAbpLoginResultType : byte{/// <summary>/// 手机号码未验证/// </summary>UserMobilePhoneNotConfirmed = 10}
}

LogInManager.cs扩展这个类,代码如下:

文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Application\Authorization\LogInManager.cs

private readonly IMultiTenancyConfig _multiTenancyConfig;
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IRepository<Tenant> _tenantRepository;
private readonly AbpUserManager<Role, User> _userManager;
private readonly UserStore _userStore;

public LogInManager(UserManager userManager, IMultiTenancyConfig multiTenancyConfig, IRepository<Tenant> tenantRepository, IUnitOfWorkManager unitOfWorkManager, ISettingManager settingManager, IRepository<UserLoginAttempt, long> userLoginAttemptRepository, IUserManagementConfig userManagementConfig, IIocResolver iocResolver, RoleManager roleManager,UserStore userStore): base(userManager, multiTenancyConfig, tenantRepository, unitOfWorkManager, settingManager, userLoginAttemptRepository, userManagementConfig, iocResolver, roleManager){_multiTenancyConfig = multiTenancyConfig;_unitOfWorkManager = unitOfWorkManager;_tenantRepository = tenantRepository;_userManager = userManager;_userStore = userStore;}

public virtual async Task<AbpLoginResult<Tenant, User>> LoginByMobileAsync(string mobilePhone, string plainPassword, string tenancyName = null,bool shouldLockout = true){var result = await LoginByMobileAsyncInternal(mobilePhone, plainPassword, tenancyName, shouldLockout);await SaveLoginAttempt(result, tenancyName, mobilePhone);return result;}protected async Task<AbpLoginResult<Tenant, User>> LoginByMobileAsyncInternal(string mobilePhone, string plainPassword, string tenancyName, bool shouldLockout){if (mobilePhone.IsNullOrEmpty()){throw new ArgumentNullException(nameof(mobilePhone));}if (plainPassword.IsNullOrEmpty()){throw new ArgumentNullException(nameof(plainPassword));}//Get and check tenantTenant tenant = null;using (_unitOfWorkManager.Current.SetTenantId(null)){if (!_multiTenancyConfig.IsEnabled){tenant = await GetDefaultTenantAsync();}else if (!string.IsNullOrWhiteSpace(tenancyName)){tenant = await _tenantRepository.FirstOrDefaultAsync(t => t.TenancyName == tenancyName);if (tenant == null){return new AbpLoginResult<Tenant, User>(AbpLoginResultType.InvalidTenancyName);}if (!tenant.IsActive){return new AbpLoginResult<Tenant, User>(AbpLoginResultType.TenantIsNotActive, tenant);}}}var tenantId = tenant == null ? (int?)null : tenant.Id;using (_unitOfWorkManager.Current.SetTenantId(tenantId)){var user = await _userStore.FindByPhoneNumberAsync(tenantId, mobilePhone);if (user == null){return new AbpLoginResult<Tenant, User>(AbpLoginResultType.InvalidUserNameOrEmailAddress, tenant);}_userManager.InitializeLockoutSettings(tenantId);if (await _userManager.IsLockedOutAsync(user.Id)){return new AbpLoginResult<Tenant, User>(AbpLoginResultType.LockedOut, tenant, user);}var verificationResult = _userManager.PasswordHasher.VerifyHashedPassword(user.Password, plainPassword);if (verificationResult != PasswordVerificationResult.Success){if (shouldLockout){if (await TryLockOutAsync(tenantId, user.Id)){return new AbpLoginResult<Tenant, User>(AbpLoginResultType.LockedOut, tenant, user);}}return new AbpLoginResult<Tenant, User>(AbpLoginResultType.InvalidPassword, tenant, user);}await _userManager.ResetAccessFailedCountAsync(user.Id);return await CreateLoginByMobileResultAsync(user, tenant);}}protected async Task<AbpLoginResult<Tenant, User>> CreateLoginByMobileResultAsync(User user, Tenant tenant = null){if (!user.IsActive){return new AbpLoginResult<Tenant, User>(AbpLoginResultType.UserIsNotActive);}if (!user.IsPhoneNumberConfirmed){return new AbpLoginResult<Tenant, User>((AbpLoginResultType)MyAbpLoginResultType.UserMobilePhoneNotConfirmed);}user.LastLoginTime = Clock.Now;await _userManager.AbpStore.UpdateAsync(user);await _unitOfWorkManager.Current.SaveChangesAsync();return new AbpLoginResult<Tenant, User>(tenant,user,await _userManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie));}

Web项目

CodeHelper.cs添加此类,代码如下:

文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Web\Helpers\CodeHelper.cs

/// <summary>/// 生成6位手机验证码/// </summary>/// <returns></returns>public static string SetNewPhoneCode(){var c = RandomHelper.GetRandom(100000, 999999);return c + "";}

AccountController.cs添加如下代码,大概351行位置:

文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Web\Controllers\AccountController.cs

/// <summary>/// 手机注册/// </summary>/// <param name="model"></param>/// <returns></returns>public ActionResult RegisterByMobile(){return MobileRegisterView(new MobileRegisterViewModel{TenancyName = _tenancyNameFinder.GetCurrentTenancyNameOrNull(),PasswordComplexitySetting = JsonConvert.DeserializeObject<PasswordComplexitySetting>(SettingManager.GetSettingValue(AppSettings.Security.PasswordComplexity))});}public ActionResult MobileRegisterView(MobileRegisterViewModel model){CheckSelfRegistrationIsEnabled();ViewBag.IsMultiTenancyEnabled = _multiTenancyConfig.IsEnabled;return View("RegisterByMobile", model);}

 [HttpPost][UnitOfWork]public virtual async Task<ActionResult> RegisterByMobile(MobileRegisterViewModel model){try{CheckSelfRegistrationIsEnabled();VaildateMobile(model.MobilePhoneCode);//判断手机号是否被占用var ur = await _userManager.Users.Where(u => u.PhoneNumber == model.MobilePhone).FirstOrDefaultAsync();if (ur != null){throw new UserFriendlyException(L("OccupiedMobilePhone"));}if (!_multiTenancyConfig.IsEnabled){model.TenancyName = Tenant.DefaultTenantName;}else if (model.TenancyName.IsNullOrEmpty()){throw new UserFriendlyException(L("TenantNameCanNotBeEmpty"));}CurrentUnitOfWork.SetTenantId(null);var tenant = await GetActiveTenantAsync(model.TenancyName);CurrentUnitOfWork.SetTenantId(tenant.Id);if (!await SettingManager.GetSettingValueForTenantAsync<bool>(AppSettings.UserManagement.AllowSelfRegistration, tenant.Id)){throw new UserFriendlyException(L("SelfUserRegistrationIsDisabledMessage_Detail"));}await _userPolicy.CheckMaxUserCountAsync(tenant.Id);//Getting tenant-specific settingsvar isNewRegisteredUserActiveByDefault = await SettingManager.GetSettingValueForTenantAsync<bool>(AppSettings.UserManagement.IsNewRegisteredUserActiveByDefault, tenant.Id);var isEmailConfirmationRequiredForLogin = await SettingManager.GetSettingValueForTenantAsync<bool>(AbpZeroSettingNames.UserManagement.IsEmailConfirmationRequiredForLogin, tenant.Id);var user = new User{TenantId = tenant.Id,IsActive = isNewRegisteredUserActiveByDefault,PhoneNumber = model.MobilePhone,IsPhoneNumberConfirmed = true};ExternalLoginInfo externalLoginInfo = null;//用户名或密码为空,抛出异常if (model.MobilePhone.IsNullOrEmpty() || model.Password.IsNullOrEmpty()){throw new UserFriendlyException(L("FormIsNotValidMessage"));}user.UserName = model.MobilePhone;user.Password = new PasswordHasher().HashPassword(model.Password);user.Roles = new List<UserRole>();foreach (var defaultRole in await _roleManager.Roles.Where(r => r.IsDefault).ToListAsync()){user.Roles.Add(new UserRole(tenant.Id, user.Id, defaultRole.Id));}CheckErrors(await _userManager.CreateAsync(user));await _unitOfWorkManager.Current.SaveChangesAsync();//通知await _notificationSubscriptionManager.SubscribeToAllAvailableNotificationsAsync(user.ToUserIdentifier());await _appNotifier.WelcomeToTheApplicationAsync(user);await _appNotifier.NewUserRegisteredAsync(user);//如果可能,直接登录if (user.IsActive && user.IsPhoneNumberConfirmed){AbpLoginResult<Tenant, User> loginResult;loginResult = await GetLoginByMobileResultAsync(user.UserName, model.Password, tenant.TenancyName);if (loginResult.Result == AbpLoginResultType.Success){await SignInAsync(loginResult.User, loginResult.Identity);return Redirect(Url.Action("Index", "Application"));}Logger.Warn("新注册的用户无法登录。 这不应该是正常。 登录结果: " + loginResult.Result);}return View("RegisterResult", new RegisterResultViewModel{TenancyName = tenant.TenancyName,NameAndSurname = user.Name + " " + user.Surname,UserName = user.UserName,EmailAddress = user.EmailAddress,IsActive = user.IsActive,IsEmailConfirmationRequired = isEmailConfirmationRequiredForLogin});}catch (UserFriendlyException ex){ViewBag.IsMultiTenancyEnabled = _multiTenancyConfig.IsEnabled;ViewBag.UseCaptcha = UseCaptchaOnRegistration();ViewBag.ErrorMessage = ex.Message;ViewBag.ErrorDetails = ex.Details;return View("RegisterByMobile", model);}}

/// <summary>/// 手机验证码验证/// </summary>/// <param name="mobilePhoneCode"></param>private void VaildateMobile(string mobilePhoneCode){if (mobilePhoneCode.Length != Authorization.Users.User.MobileCodeLength){throw new UserFriendlyException(string.Format("验证码必须为 {0} 位!", Authorization.Users.User.MobileCodeLength));}//手机验证码效验var phoneCode = Session["PhoneCode"];var now = Session["PhoneCodeDateTime"];if (phoneCode == null || string.IsNullOrWhiteSpace(phoneCode.ToString())){throw new UserFriendlyException("您输入的验证码无效!");}var nowTime = Convert.ToDateTime(now);var t = DateTime.Now - nowTime;if (t.TotalSeconds >= 180){throw new UserFriendlyException("您输入的验证码无效!");}if (!mobilePhoneCode.Equals(phoneCode.ToString())){throw new UserFriendlyException("您输入的验证码不正确!");}}private async Task<AbpLoginResult<Tenant, User>> GetLoginByMobileResultAsync(string mobilePhone, string password, string tenancyName){var loginResult = await _logInManager.LoginByMobileAsync(mobilePhone, password, tenancyName);switch (loginResult.Result){case AbpLoginResultType.Success:return loginResult;default:throw _abpLoginResultTypeHelper.CreateExceptionForFailedLoginAttempt(loginResult.Result, mobilePhone, tenancyName);}}

VerificationCodeController.cs添加此控制器,代码如下:

文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Web\Controllers\VerificationCodeController.cs

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Abp.Net.Sms;
using Abp.UI;
using MyCompanyName.AbpZeroTemplate.Authorization.Users;
using MyCompanyName.AbpZeroTemplate.MultiTenancy;
using MyCompanyName.AbpZeroTemplate.Validation;
using MyCompanyName.AbpZeroTemplate.Web.Helpers;namespace MyCompanyName.AbpZeroTemplate.Web.Controllers
{public class VerificationCodeController : AbpZeroTemplateControllerBase{private readonly UserManager _userManager;private readonly ISmsSender _smsSender;private readonly TenantManager _tenantManager;private readonly IUserEmailer _userEmailer;public VerificationCodeController(UserManager userManager,ISmsSender smsSender,TenantManager tenantManager,IUserEmailer userEmailer){_userManager = userManager;_smsSender = smsSender;_tenantManager = tenantManager;_userEmailer = userEmailer;}#region 手机/// <summary>/// 注册时使用,发送手机验证码/// </summary>/// <param name="phoneNumber"></param>/// <returns></returns>
        [HttpPost]public async Task<JsonResult> SendMobileCode(string phoneNumber){try{if (!new ValidationHelper().IsPhoneNumber(phoneNumber)){throw new UserFriendlyException("您输入了无效的手机号码!");}//检查手机是否已被注册var user = await _userManager.Users.Where(u => u.PhoneNumber == phoneNumber).FirstOrDefaultAsync();if (user != null){throw new UserFriendlyException(L("OccupiedMobilePhone"));}//生成6位数字验证码var code = CodeHelper.SetNewPhoneCode();//发送验证码await _smsSender.SendAsync(phoneNumber, AbpZeroTemplateConsts.SmsTemplateCommonCode, "{\"code\":\"" + code + "\"}");//存储验证码、手机号、时间,以备验证使用Session["PhoneCode"] = code;Session["PhoneNumber"] = phoneNumber;Session["PhoneCodeDateTime"] = DateTime.Now;return Json("OK", JsonRequestBehavior.DenyGet);}catch (Exception ex){throw new UserFriendlyException(ex.Message);}}/// <summary>///验证手机时使用,发送手机验证码/// </summary>/// <param name="phoneNumber"></param>/// <returns></returns>
        [HttpPost]public async Task<JsonResult> SendMobileCodeByVerificationMobile(string phoneNumber){try{if (!new ValidationHelper().IsPhoneNumber(phoneNumber)){throw new UserFriendlyException("您输入了无效的手机号码!");}//检查手机是否已被注册var user = await _userManager.Users.Where(u => u.PhoneNumber == phoneNumber && u.Id != AbpSession.UserId).FirstOrDefaultAsync();if (user != null){throw new UserFriendlyException(L("OccupiedMobilePhone"));}//生成6位数字验证码var code = CodeHelper.SetNewPhoneCode();//发送验证码await _smsSender.SendAsync(phoneNumber, AbpZeroTemplateConsts.SmsTemplateCommonCode, "{\"code\":\"" + code + "\"}");//存储验证码、手机号、时间,以备验证使用Session["PhoneCode"] = code;Session["PhoneNumber"] = phoneNumber;Session["PhoneCodeDateTime"] = DateTime.Now;return Json("OK", JsonRequestBehavior.DenyGet);}catch (Exception ex){throw new UserFriendlyException(ex.Message);}}#endregion#region private/// <summary>/// 检查手机号码是否已被注册,未注册抛出异常/// </summary>/// <param name="mobilePhone"></param>/// <returns></returns>private async Task<User> GetUserByCheckingMobile(string mobilePhone){var user = await _userManager.Users.Where(u => u.PhoneNumber == mobilePhone).FirstOrDefaultAsync();if (user == null){throw new UserFriendlyException(L("InvalidMobilePhone"));}return user;}#endregion}
}

添加视图

添加RegisterByMobile.cshtml视图文件,代码如下:

文件路径:D:\abpweb\PddSellerAssistant\PddSellerAssistant.Web\Views\Account\RegisterByMobile.cshtml

@model MyCompanyName.AbpZeroTemplate.Web.Models.Account.MobileRegisterViewModel
@using System.Web.Script.Serialization
@using Abp.Extensions
@using Abp.Web.Mvc.Extensions
@using MyCompanyName.AbpZeroTemplate.MultiTenancy
@using Recaptcha.Web
@using Recaptcha.Web.Mvc
@section Scripts
{<script>window.passwordComplexitySetting = @(new JavaScriptSerializer().Serialize(Model.PasswordComplexitySetting).Replace("\"", ""));</script>@Html.IncludeScript("~/Views/Account/RegisterByMobile.js")
}
<form class="register-form" action="@Url.Action("RegisterByMobile")" method="post"><h3>@L("MobileRegister")</h3>@if (@ViewBag.ErrorMessage != null){<div class="alert alert-danger"><i class="fa fa-warning"></i> @ViewBag.ErrorMessage@if (@ViewBag.ErrorDetails != null){<br />@ViewBag.ErrorDetails}</div>}@Html.AntiForgeryToken()@if (ViewBag.IsMultiTenancyEnabled){if (Model.TenancyName.IsNullOrEmpty()){<p class="hint">@L("TenantInformations")</p><div class="form-group"><label class="control-label visible-ie8 visible-ie9">@L("TenancyName")</label><input class="form-control placeholder-no-fix input-ltr" type="text" placeholder="@L("TenancyName")" name="TenancyName" value="@(Model.TenancyName ?? "")" required maxlength="@Tenant.MaxTenancyNameLength" /></div>}else{<input type="hidden" name="TenancyName" value="@Model.TenancyName" />}}<p class="hint">@L("AccountSettings")</p><div class="form-group"><label class="control-label visible-ie8 visible-ie9">@L("MobilePhone")</label><input class="form-control placeholder-no-fix" type="text" placeholder="@L("MobilePhone")" id="MobilePhone" name="MobilePhone" required value="@Model.MobilePhone" maxlength="@MyCompanyName.AbpZeroTemplate.Authorization.Users.User.MaxMobilePhoneLength" /></div><div class="form-group"><div class="input-group input-group-lg"><div class="input-group-control"><input type="text" class="form-control input-sm" autocomplete="off" id="MobileCode" name="MobilePhoneCode" value="" required placeholder="验证码"></div><span class="input-group-btn btn-right"><button id="SendMobileCode" class="btn green-haze" type="button">发送验证码</button></span></div></div><div class="form-group"><label class="control-label visible-ie8 visible-ie9">@L("Password")</label><input class="form-control placeholder-no-fix" type="password" autocomplete="off" id="RegisterPassword" placeholder="@L("Password")" name="Password" required /></div><div class="form-group"><label class="control-label visible-ie8 visible-ie9">@L("PasswordRepeat")</label><input class="form-control placeholder-no-fix" type="password" autocomplete="off" placeholder="@L("PasswordRepeat")" name="PasswordRepeat" required /></div><div class="form-actions"><a href="@Url.Action("Login", "Account")"><button type="button" id="register-back-btn" class="btn btn-default">@L("Back")</button></a><a href="@Url.Action("Register","Account")">邮箱注册</a><button type="submit" id="register-submit-btn" class="btn btn-success uppercase pull-right">@L("Submit")</button></div>
</form>

JS文件

添加一个跟视图名称一样的JS文件 RegisterByMobile.js,代码如下:

文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Web\Views\Account\RegisterByMobile.js

var CurrentPage = function () {jQuery.validator.addMethod("customUsername", function (value, element) {if (value === $('input[name="MobilePhoneCode"]').val()) {return true;}return !$.validator.methods.email.apply(this, arguments);}, abp.localization.localize("RegisterFormUserNameInvalidMessage"));var _passwordComplexityHelper = new app.PasswordComplexityHelper();var handleRegister = function () {$('.register-form').validate({rules: {PasswordRepeat: {equalTo: "#RegisterPassword"},MobilePhone: {required: true,},MobileCode: {required: true,}},submitHandler: function (form) {form.submit();}});var $element = $('#RegisterPassword');_passwordComplexityHelper.setPasswordComplexityRules($element, window.passwordComplexitySetting);/**发送验证码*/$(sendMobileCodeBtn).click(function () {var phoneNumber = $("#MobilePhone").val();if (checkMobile(phoneNumber) == false) {return false;}curCount = count;abp.ajax({contentType: app.consts.contentTypes.formUrlencoded,url: '/VerificationCode/SendMobileCode',data: { phoneNumber: phoneNumber }}).done(function (result) {if (result.result == "OK") {// 设置按钮显示效果,倒计时$(sendMobileCodeBtn).attr("disabled", "true");$(sendMobileCodeBtn).text("请在" + curCount + "秒内输入验证码");InterValObj = window.setInterval(SetRemainTime, 1000); // 启动计时器,1秒执行一次} else {$(sendMobileCodeBtn).val("重新发送验证码");}});});}return {init: function () {handleRegister();}};}();
var InterValObj; //timer变量,控制时间
var count = 60 * 3; //间隔函数,1秒执行
var curCount;//当前剩余秒数
var codeLength = 6;//验证码长度
var sendMobileCodeBtn = $("#SendMobileCode");
//timer处理函数
function SetRemainTime() {if (curCount == 0) {window.clearInterval(InterValObj);// 停止计时器$(sendMobileCodeBtn).removeAttr("disabled");// 启用按钮$(sendMobileCodeBtn).text("重新发送验证码");code = ""; // 清除验证码。如果不清除,过时间后,输入收到的验证码依然有效} else {curCount--;$(sendMobileCodeBtn).text("请在" + curCount + "秒内输入验证码");}
}function checkMobile(phone) {if (!(/^1[3|4|5|8][0-9]\d{4,8}$/.test(phone))) {abp.message.error('您输入了无效的手机号', '错误');return false;}
}

手机注册入口

Register.cshtml添加手机号注册连接,代码如下:

文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Web\Views\Account\Register.cshtml

<div class="form-actions"><a href="@Url.Action("Login", "Account")"><button type="button" id="register-back-btn" class="btn btn-default">@L("Back")</button></a><a href="@Url.Action("RegisterByMobile","Account")">手机号注册</a><button type="submit" id="register-submit-btn" class="btn btn-success uppercase pull-right">@L("Submit")</button></div>

保存生成项目,浏览器打开注册页面,如下图所示:

注册成功会自动登录系统,此时注销用户,再次登录会提示“登录失败”,接下来修改登录功能,使之同时支持手机、邮箱、用户名登录。

登录功能修改

AccountController.cs修改Login Post方法,143行位置代码修改如下:

文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Web\Controllers\AccountController.cs

AbpLoginResult<Tenant,Authorization.Users.User > loginResult = null;if (new ValidationHelper().IsPhoneNumber(loginModel.UsernameOrEmailAddress)){loginResult =awaitGetLoginByMobileResultAsync(loginModel.UsernameOrEmailAddress, loginModel.Password,loginModel.TenancyName);}else{loginResult = await GetLoginResultAsync(loginModel.UsernameOrEmailAddress, loginModel.Password, loginModel.TenancyName);}

AbpZeroTemplate-zh-CN.xml ,代码修改如下:

文件路径:D:\abp version\aspnet-zero-3.4.0\aspnet-zero-3.4.0\src\MyCompanyName.AbpZeroTemplate.Core\Localization\AbpZeroTemplate\AbpZeroTemplate-zh-CN.xml

<text name="UserNameOrEmail" value="手机或用户名或邮箱地址" />

生成项目,再次以手机、邮箱、用户名登录,已经都可以正常登录。

手机注册登录功能到这里修改完成,篇幅很多,基本把整个解决方案翻了一篇。

返回总目录

转载于:https://www.cnblogs.com/shensigzs/p/8289721.html

8、ABPZero系列教程之拼多多卖家工具 添加手机注册登录功能相关推荐

  1. ABPZero系列教程之拼多多卖家工具

    此系列文章围绕着拼多多卖家工具来介绍ABPZero的使用,内容包括手机登录.手机注册.拼团提醒.微信公众号绑定帐号.有拼团发送消息到微信公众号(只要关注过微信公众号并已绑定系统帐号). 学习此系列必备 ...

  2. 1、ABPZero系列教程之拼多多卖家工具 前言

    此系列文章围绕着拼多多卖家工具来介绍ABPZero的使用,内容包括手机登录.手机注册.拼团提醒.微信公众号绑定帐号.有拼团发送消息到微信公众号(只要关注过微信公众号并已绑定系统帐号). 学习此系列必备 ...

  3. 12、ABPZero系列教程之拼多多卖家工具 拼团提醒功能登录拼多多实现

    上篇文章已经完成了整个拼多多拼团提醒功能,本篇继续完成拼多多帐号登录,拼多多帐号登录的目的是为了获取拼团商品的SKU和订单号,便于商家备货. 以下是拼多多官方的后台登录,要实现的功能并不是直接在这里登 ...

  4. 拼多多后台x4.0监控mysql_11、ABPZero系列教程之拼多多卖家工具 拼团提醒功能页面实现...

    上一篇讲解了拼团提醒逻辑功能实现,现在继续实现页面功能. Core项目 打开AbpZeroTemplate-zh-CN.xml语言文件,在末尾添加如下代码: 文件路径:D:\abp version\a ...

  5. 7、ABPZero系列教程之拼多多卖家工具 修改注册功能

    本篇开始进入重头戏,之前的几篇文章都是为了现在的功能作准备.前面教程已经讲到修改User表结构,接下来就需要修改注册逻辑代码. 注册页面 修改Register.cshtml,备注如下代码: 文件路径: ...

  6. abp zero mysql_2、ABPZero系列教程之拼多多卖家工具 更改数据库为Mysql

    因为要部署项目到云服务器,不想在服务器上装SqlServer,所以需要把项目改为Mysql. 项目初始化 1.下载项目压缩包,前面文章已经说到,可以加群到群文件里下载.解压缩下载的项目源码,使用VS2 ...

  7. 4、ABPZero系列教程之拼多多卖家工具 集成短信发送模块

    ABPZero并没有手机短信发送功能,现在我们来集成一个,为后面注册.登录作铺垫. 阿里云短信服务 首先需要在阿里云开通短信服务,连接地址 开通后,在签名管理中添加一个签名 在模板管理中添加一个模板, ...

  8. 5、ABPZero系列教程之拼多多卖家工具 修改User表结构

    毕竟这个框架是外国人开发的,对于我们国人来说还是有些地方并不合适,就好比如注册时需要填写名字.姓氏一样,今天要说的就是如何去掉这2个字段. 先看如下修改完成的效果图 User表结构修改 修改User类 ...

  9. php weixin provider,14、ABPZero系列教程之拼多多卖家工具 新建微信公众号模块

    说是模块,其实在MVC中就是区域,新建一个区域专门管理整个微信功能. Web项目新建区域 在Web项目Areas目录下新建一个区域,名称为"Weixin",如下图: 接着打开web ...

最新文章

  1. 【Sql Server】数据库的3大服务
  2. jittor和pytorch网络对比之context_encoder
  3. bzoj 1045 [HAOI2008] 糖果传递 —— 贪心
  4. android 宏替换_android 模拟宏定义,实现Debug amp; Release 模式-一团网
  5. mybatis java8_mybatis如何使用Java8的日期LocalDate和LocalDateTime详解
  6. 5 useMemouseCallback
  7. 【转】Oracle 执行动态语句
  8. 不常用却很有妙用的事件及方法
  9. Flex练习-打游戏
  10. java exe指的是什么_Java程序的执行过程中用到一套JDK工具,其中java.exe是指( )。
  11. 风车im即时通讯源码
  12. matlab电力系统建模仿真实验,电力系统建模及仿真课程设计
  13. 【测试人生】安卓FPS测试详解
  14. Http请求报文解析
  15. 董明珠的“三个谜团”
  16. uniapp ucharts统计图表
  17. 四色印刷和专色印刷的区别是什么?
  18. 网易云音乐的亏损,是社区经济的通病?
  19. 项目八 51单片机WIFI控制继电器
  20. 朱则荣:图王与王通的软文营销境界

热门文章

  1. 使用Charles 抓取数据包
  2. python大学课程实验六_Python程序设计实验六:函数
  3. Altium desiger10安装破解过程
  4. docker 垃圾清理命令
  5. vue 根据链接生成二维码(功能实现)
  6. 什么是量子安全?量子计算时代下的基本安全技术
  7. 欧朋Opera 浏览器(打不开百度)提示“您的连接不是私密连接”,解决办法
  8. 微信ios版本的两个灰度功能和一些小改变
  9. ROS小车实践记录(一)
  10. ubuntu 安装kali_如何在Linux,Windows,Kali,Ubuntu,Mint和示例中安装和使用exiftool