stevenhqq

无知逼着我不断学习,唯有这种方式,才能感觉自己还有点价值。

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

在这个案例中,AccountModels文件中Models部分主要是编写了用户登陆、注册、修改密码模型的代码。这些代码都容易理解,用于承载MVC各部件中数传递的Model。

添加注释后的代码如下:

View Code
1 #region Models 账户模型(修改密码、登陆、注册)
2
3 /// <summary>
4 /// 修改密码模型
5 /// </summary>
6   public class ChangePasswordModel
7 {
8 /// <summary>
9 /// 旧密码
10 /// </summary>
11   [Required]
12 [DataType(DataType.Password)]
13 [Display(Name = "Current password")]
14 public string OldPassword { get; set; }
15
16 /// <summary>
17 /// 新密码
18 /// </summary>
19   [Required]
20 [ValidatePasswordLength]
21 [DataType(DataType.Password)]
22 [Display(Name = "New password")]
23 public string NewPassword { get; set; }
24
25 /// <summary>
26 /// 确认新密码
27 /// </summary>
28   [DataType(DataType.Password)]
29 [Display(Name = "Confirm new password")]
30 [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
31 public string ConfirmPassword { get; set; }
32 }
33
34 /// <summary>
35 /// 登陆模型
36 /// </summary>
37   public class LogOnModel
38 {
39 /// <summary>
40 /// 用户名
41 /// </summary>
42   [Required]
43 [Display(Name = "User name")]
44 public string UserName { get; set; }
45
46 /// <summary>
47 /// 密码
48 /// </summary>
49 [Required]
50 [DataType(DataType.Password)]
51 [Display(Name = "Password")]
52 public string Password { get; set; }
53
54 /// <summary>
55 /// 是否记住密码
56 /// </summary>
57 [Display(Name = "Remember me?")]
58 public bool RememberMe { get; set; }
59 }
60
61 /// <summary>
62 /// 注册模型
63 /// </summary>
64 public class RegisterModel
65 {
66 /// <summary>
67 /// 用户名
68 /// </summary>
69 [Required]
70 [Display(Name = "User name")]
71 public string UserName { get; set; }
72
73 /// <summary>
74 /// 电子邮件
75 /// </summary>
76 [Required]
77 [DataType(DataType.EmailAddress)]
78 [Display(Name = "Email address")]
79 public string Email { get; set; }
80
81 /// <summary>
82 /// 密码
83 /// </summary>
84 [Required]
85 [ValidatePasswordLength]
86 [DataType(DataType.Password)]
87 [Display(Name = "Password")]
88 public string Password { get; set; }
89
90 /// <summary>
91 /// 确认密码
92 /// </summary>
93 [DataType(DataType.Password)]
94 [Display(Name = "Confirm password")]
95 [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
96 public string ConfirmPassword { get; set; }
97 }
98 #endregion

源代码中Services部分主要是做成员管理服务、表单验证服务的。为了将来好做单元测试,所以编写了ImembershipService和IFormsAuthenticationService两个接口,以及实现着两个接口所对应的类AccountMembershipService和FormsAuthenticationService。

注释好的代码如下:

View Code
1 #region Services 成员管理服务 表单验证服务
2 // The FormsAuthentication type is sealed and contains static members, so it is difficult to
3 // unit test code that calls its members. The interface and helper class below demonstrate
4 // how to create an abstract wrapper around such a type in order to make the AccountController
5 // code unit testable.
6 // FormsAuthentication类是个密封的,并且包含静态成员的类型。因此很难使用单元测试来调用其成员。
7 // 下面将围绕这样一个抽象的包装类型来创建接口和辅助类,以便使AccountController类来进行单元测试。
8
9 /// <summary>
10 /// 成员管理服务接口
11 /// </summary>
12 public interface IMembershipService
13 {
14 /// <summary>
15 /// 最小密码长度
16 /// </summary>
17 int MinPasswordLength { get; }
18 /// <summary>
19 /// 验证用户
20 /// </summary>
21 /// <param name="userName">用户名</param>
22 /// <param name="password">密码</param>
23 /// <returns>是否通过验证</returns>
24 bool ValidateUser(string userName, string password);
25 /// <summary>
26 /// 创建用户
27 /// </summary>
28 /// <param name="userName">用户名</param>
29 /// <param name="password">密码</param>
30 /// <param name="email">电子邮件地址</param>
31 /// <returns>成员管理创建状态</returns>
32 MembershipCreateStatus CreateUser(string userName, string password, string email);
33 /// <summary>
34 /// 修改密码
35 /// </summary>
36 /// <param name="userName">用户名</param>
37 /// <param name="oldPassword">旧密码</param>
38 /// <param name="newPassword">新密码</param>
39 /// <returns>修改是否成功</returns>
40 bool ChangePassword(string userName, string oldPassword, string newPassword);
41 }
42
43 /// <summary>
44 /// 成员管理服务类(实现成员管理服务接口)
45 /// </summary>
46 public class AccountMembershipService : IMembershipService
47 {
48 /// <summary>
49 /// 成员管理提供者
50 /// </summary>
51 private readonly MembershipProvider _provider;
52
53 /// <summary>
54 /// 不带参数的构造函数
55 /// </summary>
56 public AccountMembershipService()
57 : this(null)
58 {
59 }
60
61 /// <summary>
62 /// 使用成员管理提供者来构建该类
63 /// </summary>
64 /// <param name="provider">成员管理提供者</param>
65 public AccountMembershipService(MembershipProvider provider)
66 {
67 //如果有值传入则使用传入的值,否则使用默认的成员管理提供者
68 _provider = provider ?? Membership.Provider;
69 }
70
71 /// <summary>
72 /// 获取密码所要求的最小长度
73 /// </summary>
74 public int MinPasswordLength
75 {
76 get
77 {
78 return _provider.MinRequiredPasswordLength;
79 }
80 }
81
82 /// <summary>
83 /// 验证是否存在制定的用户名和密码是否存在
84 /// </summary>
85 /// <param name="userName">用户名</param>
86 /// <param name="password">密码</param>
87 /// <returns>是否通过验证</returns>
88 public bool ValidateUser(string userName, string password)
89 {
90 //如果用户名为空,则抛出参数异常“值不能为空”
91 if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
92 if (String.IsNullOrEmpty(password)) throw new ArgumentException("Value cannot be null or empty.", "password");
93
94 return _provider.ValidateUser(userName, password);
95 }
96
97 /// <summary>
98 /// 创建用户
99 /// </summary>
100 /// <param name="userName">用户名</param>
101 /// <param name="password">密码</param>
102 /// <param name="email">电子邮件地址</param>
103 /// <returns>成员管理创建状态</returns>
104 public MembershipCreateStatus CreateUser(string userName, string password, string email)
105 {
106 //验证参数是否填写,否则抛出参数异常“值不能为空”
107 if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
108 if (String.IsNullOrEmpty(password)) throw new ArgumentException("Value cannot be null or empty.", "password");
109 if (String.IsNullOrEmpty(email)) throw new ArgumentException("Value cannot be null or empty.", "email");
110
111 MembershipCreateStatus status;
112 _provider.CreateUser(userName, password, email, "question", "answer", true, null, out status);
113 return status;
114 }
115
116 /// <summary>
117 /// 修改密码
118 /// </summary>
119 /// <param name="userName">用户名</param>
120 /// <param name="oldPassword">旧密码</param>
121 /// <param name="newPassword">新密码</param>
122 /// <returns>修改是否成功</returns>
123 public bool ChangePassword(string userName, string oldPassword, string newPassword)
124 {
125 //验证参数是否填写,否则抛出参数异常“值不能为空”
126 if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
127 if (String.IsNullOrEmpty(oldPassword)) throw new ArgumentException("Value cannot be null or empty.", "oldPassword");
128 if (String.IsNullOrEmpty(newPassword)) throw new ArgumentException("Value cannot be null or empty.", "newPassword");
129
130 // The underlying ChangePassword() will throw an exception rather
131 // than return false in certain failure scenarios.
132 // 底层方法ChangePassword()有可能在某些情况下会抛出异常,
133 // 因此在这种情况下应该返回false
134 try
135 {
136 MembershipUser currentUser = _provider.GetUser(userName, true /* userIsOnline */);
137 return currentUser.ChangePassword(oldPassword, newPassword);
138 }
139 catch (ArgumentException)
140 {
141 return false;
142 }
143 catch (MembershipPasswordException)
144 {
145 return false;
146 }
147 }
148 }
149
150 /// <summary>
151 /// 表单验证接口
152 /// </summary>
153 public interface IFormsAuthenticationService
154 {
155 /// <summary>
156 /// 登陆
157 /// </summary>
158 /// <param name="userName">用户名</param>
159 /// <param name="createPersistentCookie">是否创建持久性Cookie</param>
160 void SignIn(string userName, bool createPersistentCookie);
161 /// <summary>
162 /// 注销
163 /// </summary>
164 void SignOut();
165 }
166
167 /// <summary>
168 /// 表单验证服务(实现表单验证接口)
169 /// </summary>
170 public class FormsAuthenticationService : IFormsAuthenticationService
171 {
172 /// <summary>
173 /// 登陆
174 /// </summary>
175 /// <param name="userName">用户名</param>
176 /// <param name="createPersistentCookie">是否创建持久性Cookie</param>
177 public void SignIn(string userName, bool createPersistentCookie)
178 {
179 if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
180
181 FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
182 }
183 /// <summary>
184 /// 注销
185 /// </summary>
186 public void SignOut()
187 {
188 FormsAuthentication.SignOut();
189 }
190 }
191 #endregion

AccountModel.cs最后一个部分是Validation,用于验证数据用。

其中有静态类AccountValidation,主要用作账户验证的。当账户登录、注册等操作的时候出现了错误消息的话,可以使用该类中的ErrorCodeToString方法将错误转换成字符串,以便在界面上面呈现。

ValidatePasswordLengthAttribute这个类是个密封类,继承自ValidationAttribute(所有验证特性的基类)特性,并实现了IClientValidatable(客户端验证)接口。该类主要是验证密码的长度。

注释后的代码如下:

View Code
1 #region Validation 验证部分
2 /// <summary>
3 /// 账户验证
4 /// </summary>
5 public static class AccountValidation
6 {
7 /// <summary>
8 /// 将错误代码转换为字符串
9 /// </summary>
10 /// <param name="createStatus">创建用户后的状态</param>
11 /// <returns></returns>
12 public static string ErrorCodeToString(MembershipCreateStatus createStatus)
13 {
14 // See http://go.microsoft.com/fwlink/?LinkID=177550 for
15 // a full list of status codes.
16 /**MembershipCreateStatus枚举值说明
17 枚举值 说明
18 Success 创建用户成功。
19 InvalidUserName 在数据库中未找到用户名。
20 InvalidPassword 密码的格式设置不正确。
21 InvalidQuestion 密码提示问题的格式设置不正确。
22 InvalidAnswer 密码提示问题答案的格式设置不正确。
23 InvalidEmail 电子邮件地址的格式设置不正确。
24 DuplicateUserName 用户名已存在于应用程序的数据库中。
25 DuplicateEmail 电子邮件地址已存在于应用程序的数据库中。
26 UserRejected 因为提供程序定义的某个原因而未创建用户。
27 InvalidProviderUserKey 提供程序用户键值的类型或格式无效。
28 DuplicateProviderUserKey 提供程序用户键值已存在于应用程序的数据库中。
29 ProviderError 提供程序返回一个未由其他 MembershipCreateStatus 枚举值描述的错误。
30 */
31
32 switch (createStatus)
33 {
34 case MembershipCreateStatus.DuplicateUserName:
35 return "Username already exists. Please enter a different user name.";
36
37 case MembershipCreateStatus.DuplicateEmail:
38 return "A username for that e-mail address already exists. Please enter a different e-mail address.";
39
40 case MembershipCreateStatus.InvalidPassword:
41 return "The password provided is invalid. Please enter a valid password value.";
42
43 case MembershipCreateStatus.InvalidEmail:
44 return "The e-mail address provided is invalid. Please check the value and try again.";
45
46 case MembershipCreateStatus.InvalidAnswer:
47 return "The password retrieval answer provided is invalid. Please check the value and try again.";
48
49 case MembershipCreateStatus.InvalidQuestion:
50 return "The password retrieval question provided is invalid. Please check the value and try again.";
51
52 case MembershipCreateStatus.InvalidUserName:
53 return "The user name provided is invalid. Please check the value and try again.";
54
55 case MembershipCreateStatus.ProviderError:
56 return "The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
57
58 case MembershipCreateStatus.UserRejected:
59 return "The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
60
61 default:
62 return "An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
63 }
64 }
65 }
66
67 /// <summary>
68 /// 验证密码长度特性
69 /// </summary>
70 [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
71 public sealed class ValidatePasswordLengthAttribute : ValidationAttribute, IClientValidatable
72 {
73 /// <summary>
74 /// 默认错误消息
75 /// </summary>
76 private const string _defaultErrorMessage = "'{0}' must be at least {1} characters long.";
77 /// <summary>
78 /// 密码所需最小长度
79 /// </summary>
80 private readonly int _minCharacters = Membership.Provider.MinRequiredPasswordLength;
81
82 public ValidatePasswordLengthAttribute()
83 : base(_defaultErrorMessage)
84 {
85 }
86
87 /// <summary>
88 /// 格式化错误消息
89 /// </summary>
90 /// <param name="name">用户名</param>
91 /// <returns>格式化后的错误消息</returns>
92 public override string FormatErrorMessage(string name)
93 {
94 return String.Format(CultureInfo.CurrentCulture, ErrorMessageString,
95 name, _minCharacters);
96 }
97
98 /// <summary>
99 /// 是否通过验证
100 /// </summary>
101 /// <param name="value">要验证的值</param>
102 /// <returns>是否通过验证</returns>
103 public override bool IsValid(object value)
104 {
105 //将传入的值转换为字符串
106 string valueAsString = value as string;
107 //当传入的值不为空,并且长度大于等于最小要求,则返回true否则返回false
108 return (valueAsString != null && valueAsString.Length >= _minCharacters);
109 }
110
111 /// <summary>
112 /// 获取客户端验证规则
113 /// </summary>
114 /// <param name="metadata"></param>
115 /// <param name="context"></param>
116 /// <returns></returns>
117 public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
118 {
119 return new[]{
120 new ModelClientValidationStringLengthRule(FormatErrorMessage(metadata.GetDisplayName()), _minCharacters, int.MaxValue)
121 };
122 }
123 }
124 #endregion

做完这个AccountModels.cs文件的注释和翻译之后,那么这个类所要做的功能基本上就一清二楚了。

posted on 2011-03-01 17:18  撕体分黑蛐蛐  阅读(1920)  评论(0编辑  收藏  举报