Dev Express 框架自定义登录添加短信验证功能
需求:登录界面改成这样
记录一下过程,以便下次操作类似的步骤有遗忘,也与大伙儿分享下,如有不当之处请指出,感谢。
参考官网文档:https://docs.devexpress.com/eXpressAppFramework/112982/task-based-help/security/how-to-use-custom-logon-parameters-and-authentication?v=18.1
具体实现步骤:
一:界面
1.自定义用户类Employee(也可以使用默认默认的PermissionPolicyUser类,如果属性满足的话)
using DevExpress.Persistent.Base; using DevExpress.Persistent.BaseImpl.PermissionPolicy; using DevExpress.Xpo; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Login2.Module.BusinessObjects { [DefaultClassOptions, DefaultProperty("UserName")] public class Employee : PermissionPolicyUser //继承默认的用户类 { public Employee(Session session) : base(session) { } //验证码 private string verificationCode; public string VerificationCode { get { return verificationCode; } set { SetPropertyValue("VerificationCode", ref verificationCode, value); } } //手机号 private string phone; public string Phone { get { return phone; } set { SetPropertyValue("Phone", ref phone, value); } } } }
2.自定义参数类:ConstomLogonParameters
using DevExpress.ExpressApp.DC; using DevExpress.Persistent.Base; using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Runtime.Serialization; using System.Text; using System.Threading.Tasks; namespace Login.Module { [DomainComponent, Serializable] [System.ComponentModel.DisplayName("Log In")] public class CustomLogonParameters : INotifyPropertyChanged, ISerializable { private string username; private string password; private string verificationCode;
[Browsable(true)] public String UserName { get { return username; } set { if (username == value) return; username = value; } } [PasswordPropertyText(true)] public string Password { get { return password; } set { if (password == value) return; password = value; } } //验证码 [Browsable(true)] public String VerificationCode { get { return verificationCode; } set { if (verificationCode == value) return; verificationCode = value; } } public CustomLogonParameters() { } // ISerializable public CustomLogonParameters(SerializationInfo info, StreamingContext context) { if (info.MemberCount > 0) { UserName = info.GetString("UserName"); Password = info.GetString("Password"); VerificationCode = info.GetString("VerificationCode"); } } private void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } public event PropertyChangedEventHandler PropertyChanged; [System.Security.SecurityCritical] public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("UserName", UserName); info.AddValue("Password", Password); info.AddValue("VerificationCode", VerificationCode); } } }
3.自定义参数验证类:CustomAuthentication 类
using DevExpress.Data.Filtering; using DevExpress.ExpressApp; using DevExpress.ExpressApp.Security; using DevExpress.Persistent.BaseImpl.PermissionPolicy; using Login.Module.BusinessObjects; using Login2.Module; using Login2.Module.BusinessObjects; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Login.Module { public class CustomAuthentication : AuthenticationBase, IAuthenticationStandard { private CustomLogonParameters customLogonParameters; public CustomAuthentication() { customLogonParameters = new CustomLogonParameters(); } public override void Logoff() { base.Logoff(); customLogonParameters = new CustomLogonParameters(); } public override void ClearSecuredLogonParameters() { customLogonParameters.Password = ""; base.ClearSecuredLogonParameters(); } // 自定义的用户类 public override object Authenticate(IObjectSpace objectSpace) { //根据用户名查找该用户 Employee employee = objectSpace.FindObject<Employee> (new BinaryOperator("UserName", customLogonParameters.UserName)); //用户不存在 if (employee == null) throw new ArgumentNullException("Employee"); //比较密码 if (!employee.ComparePassword(customLogonParameters.Password)) throw new AuthenticationException( employee.UserName, "Password mismatch."); //比较验证码 string verificationCode = employee.VerificationCode; if (verificationCode != customLogonParameters.VerificationCode) throw new AuthenticationException("VerificationCode mismatch"); return employee; } public override void SetLogonParameters(object logonParameters) { this.customLogonParameters = (CustomLogonParameters)logonParameters; } public override IList<Type> GetBusinessClasses() { return new Type[] { typeof(CustomLogonParameters) }; } public override bool AskLogonParametersViaUI { get { return true; } } public override object LogonParameters { get { return customLogonParameters; } } public override bool IsLogoffEnabled { get { return true; } } } }
4.WinApplications.cs 中替换组件
替换这个登录界面上的参数才会是我们自定义的参数,如下:
5.添加“发送验证码”按钮:
1)在Controller包下 Add Dev Express Item 选择view Controller
2)给视图层添加按钮组件:
3)设置组件属性
设置属性时,项目不能处于启动状态,不然设置不上去
属性中的TargetViewId,填下面的这个自定义参数类的detail_View 的 Id
接下来,我调了半天.....梳理一下
新建如下,
在layout下 再把上面建的组件添加上去,具体细节....
右键 add layoutViewItem
接下来就是 Controller包中添加的那个SimpleAction的属性了。
之后,再把新增的这个组件给注册了。在Module.cs 文件中添加代码。
参考:https://docs.devexpress.com/eXpressAppFramework/113475/ui-construction/controllers-and-actions/logon-form-controllers-and-actions
这个注册是组长在论坛上搜索到的。
之后界面就调好了。
二:验证
验证就稍微简单一点了。
根据它官网给的实例代码,找到校验的方法。
再根据需求自定义就好了。
还有就是发送短信验证码的按钮执行方法,在按钮的属性中可以找到。或者直接点击这个ViewController。再方法中自定义方法,例如:
private void simpleAction_yzm_Execute(object sender, SimpleActionExecuteEventArgs e) { customLogonParameters = e.CurrentObject as CustomLogonParameters; string username = customLogonParameters.UserName; if(username == null || username == "") { throw new AuthenticationException("请输入用户名"); } IObjectSpace objectSpace = Application.CreateObjectSpace(typeof(PermissionPolicyUser)); Employee user = objectSpace.FindObject<Employee> (new BinaryOperator("UserName", customLogonParameters.UserName)); string phone = user.Phone; //2.向该手机发送验证码 string verificationCode = "1234"; //验证码赋值给 用户的验证码属性 比较的时候 用 用户的验证码属性和输入的校验 //employee.VerificationCode = verificationCode; user.VerificationCode = verificationCode; objectSpace.CommitChanges(); }
注意这里按钮取登录页面上输入的参数用的对象和方法与点击Log In 有略微不同。
附CustomLogonParameter代码如下:
public class CustomLogonParameters : INotifyPropertyChanged, ISerializable { private string username; private string password; private string verificationCode; [Browsable(true)] public String UserName { get { return username; } set { if (username == value) return; username = value; } } [PasswordPropertyText(true)] public string Password { get { return password; } set { if (password == value) return; password = value; } } //验证码 [Browsable(true)] public String VerificationCode { get { return verificationCode; } set { if (verificationCode == value) return; verificationCode = value; } } public CustomLogonParameters() { } // ISerializable public CustomLogonParameters(SerializationInfo info, StreamingContext context) { if (info.MemberCount > 0) { UserName = info.GetString("UserName"); Password = info.GetString("Password"); VerificationCode = info.GetString("VerificationCode"); } } private void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } public event PropertyChangedEventHandler PropertyChanged; [System.Security.SecurityCritical] public void GetObjectData(SerializationInfo info, StreamingContext context) { info.AddValue("UserName", UserName); info.AddValue("Password", Password); info.AddValue("VerificationCode", VerificationCode); }
CustomAuthentication类代码如下:
public class CustomAuthentication : AuthenticationBase, IAuthenticationStandard { private CustomLogonParameters customLogonParameters; public CustomAuthentication() { customLogonParameters = new CustomLogonParameters(); } public override void Logoff() { base.Logoff(); customLogonParameters = new CustomLogonParameters(); } public override void ClearSecuredLogonParameters() { customLogonParameters.Password = ""; base.ClearSecuredLogonParameters(); } //public override object Authenticate(IObjectSpace objectSpace) //{ // Employee employee = objectSpace.FindObject<Employee>( // new BinaryOperator("UserName", customLogonParameters.UserName)); // if (employee == null) // throw new ArgumentNullException("Employee"); // if (!employee.ComparePassword(customLogonParameters.Password)) // throw new AuthenticationException( // employee.UserName, "Password mismatch."); // return employee; //} // 默认的用户类 //public override object Authenticate(IObjectSpace objectSpace) //{ // //根据用户名查找该用户 // PermissionPolicyUser sampleUser = objectSpace.FindObject<PermissionPolicyUser> // (new BinaryOperator("UserName", customLogonParameters.UserName)); // //用户不存在 // if (sampleUser == null) // throw new ArgumentNullException("PermissionPolicyUser"); // //比较密码 // if (!sampleUser.ComparePassword(customLogonParameters.Password)) // throw new AuthenticationException( // sampleUser.UserName, "Password mismatch."); // //比较验证码 // //if(sampleUser.VerificationCode!=customLogonParameters.VerificationCode) // if ("1234" != customLogonParameters.VerificationCode) // throw new AuthenticationException("VerificationCode mismatch"); // return sampleUser; //} // 自定义的用户类 public override object Authenticate(IObjectSpace objectSpace) { //根据用户名查找该用户 Employee employee = objectSpace.FindObject<Employee> (new BinaryOperator("UserName", customLogonParameters.UserName)); //用户不存在 if (employee == null) throw new ArgumentNullException("Employee"); //比较密码 if (!employee.ComparePassword(customLogonParameters.Password)) throw new AuthenticationException( employee.UserName, "Password mismatch."); //比较验证码 string verificationCode = employee.VerificationCode; if (verificationCode != customLogonParameters.VerificationCode) throw new AuthenticationException("VerificationCode mismatch"); return employee; } public override void SetLogonParameters(object logonParameters) { this.customLogonParameters = (CustomLogonParameters)logonParameters; } public override IList<Type> GetBusinessClasses() { return new Type[] { typeof(CustomLogonParameters) }; } public override bool AskLogonParametersViaUI { get { return true; } } public override object LogonParameters { get { return customLogonParameters; } } public override bool IsLogoffEnabled { get { return true; } }
写的比较匆忙,如有不当欢迎指出!