修改一些BUG
This commit is contained in:
283
MvcApplication1/Models/AccountModels.cs
Normal file
283
MvcApplication1/Models/AccountModels.cs
Normal file
@@ -0,0 +1,283 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Security;
|
||||
|
||||
namespace MvcApplication1.Models
|
||||
{
|
||||
|
||||
#region 模型
|
||||
[PropertiesMustMatch("NewPassword", "ConfirmPassword", ErrorMessage = "新密码和确认密码不匹配。")]
|
||||
public class ChangePasswordModel
|
||||
{
|
||||
[Required]
|
||||
[DataType(DataType.Password)]
|
||||
[DisplayName("当前密码")]
|
||||
public string OldPassword { get; set; }
|
||||
|
||||
[Required]
|
||||
[ValidatePasswordLength]
|
||||
[DataType(DataType.Password)]
|
||||
[DisplayName("新密码")]
|
||||
public string NewPassword { get; set; }
|
||||
|
||||
[Required]
|
||||
[DataType(DataType.Password)]
|
||||
[DisplayName("确认新密码")]
|
||||
public string ConfirmPassword { get; set; }
|
||||
}
|
||||
|
||||
public class LogOnModel
|
||||
{
|
||||
[Required]
|
||||
[DisplayName("用户名")]
|
||||
public string UserName { get; set; }
|
||||
|
||||
[Required]
|
||||
[DataType(DataType.Password)]
|
||||
[DisplayName("密码")]
|
||||
public string Password { get; set; }
|
||||
|
||||
[DisplayName("记住我?")]
|
||||
public bool RememberMe { get; set; }
|
||||
}
|
||||
|
||||
[PropertiesMustMatch("Password", "ConfirmPassword", ErrorMessage = "密码和确认密码不匹配。")]
|
||||
public class RegisterModel
|
||||
{
|
||||
[Required]
|
||||
[DisplayName("用户名")]
|
||||
public string UserName { get; set; }
|
||||
|
||||
[Required]
|
||||
[DataType(DataType.EmailAddress)]
|
||||
[DisplayName("电子邮件地址")]
|
||||
public string Email { get; set; }
|
||||
|
||||
[Required]
|
||||
[ValidatePasswordLength]
|
||||
[DataType(DataType.Password)]
|
||||
[DisplayName("密码")]
|
||||
public string Password { get; set; }
|
||||
|
||||
[Required]
|
||||
[DataType(DataType.Password)]
|
||||
[DisplayName("确认密码")]
|
||||
public string ConfirmPassword { get; set; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Services
|
||||
// FormsAuthentication 类型是密封的且包含静态成员,因此很难对
|
||||
// 调用其成员的代码进行单元测试。下面的接口和 Helper 类演示
|
||||
// 如何围绕这种类型创建一个抽象包装,以便可以对 AccountController
|
||||
// 代码进行单元测试。
|
||||
|
||||
public interface IMembershipService
|
||||
{
|
||||
int MinPasswordLength { get; }
|
||||
|
||||
bool ValidateUser(string userName, string password);
|
||||
MembershipCreateStatus CreateUser(string userName, string password, string email);
|
||||
bool ChangePassword(string userName, string oldPassword, string newPassword);
|
||||
}
|
||||
|
||||
public class AccountMembershipService : IMembershipService
|
||||
{
|
||||
private readonly MembershipProvider _provider;
|
||||
|
||||
public AccountMembershipService()
|
||||
: this(null)
|
||||
{
|
||||
}
|
||||
|
||||
public AccountMembershipService(MembershipProvider provider)
|
||||
{
|
||||
_provider = provider ?? Membership.Provider;
|
||||
}
|
||||
|
||||
public int MinPasswordLength
|
||||
{
|
||||
get
|
||||
{
|
||||
return _provider.MinRequiredPasswordLength;
|
||||
}
|
||||
}
|
||||
|
||||
public bool ValidateUser(string userName, string password)
|
||||
{
|
||||
if (String.IsNullOrEmpty(userName)) throw new ArgumentException("值不能为 null 或为空。", "userName");
|
||||
if (String.IsNullOrEmpty(password)) throw new ArgumentException("值不能为 null 或为空。", "password");
|
||||
|
||||
return _provider.ValidateUser(userName, password);
|
||||
}
|
||||
|
||||
public MembershipCreateStatus CreateUser(string userName, string password, string email)
|
||||
{
|
||||
if (String.IsNullOrEmpty(userName)) throw new ArgumentException("值不能为 null 或为空。", "userName");
|
||||
if (String.IsNullOrEmpty(password)) throw new ArgumentException("值不能为 null 或为空。", "password");
|
||||
if (String.IsNullOrEmpty(email)) throw new ArgumentException("值不能为 null 或为空。", "email");
|
||||
|
||||
MembershipCreateStatus status;
|
||||
_provider.CreateUser(userName, password, email, null, null, true, null, out status);
|
||||
return status;
|
||||
}
|
||||
|
||||
public bool ChangePassword(string userName, string oldPassword, string newPassword)
|
||||
{
|
||||
if (String.IsNullOrEmpty(userName)) throw new ArgumentException("值不能为 null 或为空。", "userName");
|
||||
if (String.IsNullOrEmpty(oldPassword)) throw new ArgumentException("值不能为 null 或为空。", "oldPassword");
|
||||
if (String.IsNullOrEmpty(newPassword)) throw new ArgumentException("值不能为 null 或为空。", "newPassword");
|
||||
|
||||
// 在某些出错情况下,基础 ChangePassword() 将引发异常,
|
||||
// 而不是返回 false。
|
||||
try
|
||||
{
|
||||
MembershipUser currentUser = _provider.GetUser(userName, true /* userIsOnline */);
|
||||
return currentUser.ChangePassword(oldPassword, newPassword);
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
catch (MembershipPasswordException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface IFormsAuthenticationService
|
||||
{
|
||||
void SignIn(string userName, bool createPersistentCookie);
|
||||
void SignOut();
|
||||
}
|
||||
|
||||
public class FormsAuthenticationService : IFormsAuthenticationService
|
||||
{
|
||||
public void SignIn(string userName, bool createPersistentCookie)
|
||||
{
|
||||
if (String.IsNullOrEmpty(userName)) throw new ArgumentException("值不能为 null 或为空。", "userName");
|
||||
|
||||
FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
|
||||
}
|
||||
|
||||
public void SignOut()
|
||||
{
|
||||
FormsAuthentication.SignOut();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Validation
|
||||
public static class AccountValidation
|
||||
{
|
||||
public static string ErrorCodeToString(MembershipCreateStatus createStatus)
|
||||
{
|
||||
// 请参见 http://go.microsoft.com/fwlink/?LinkID=177550 以查看
|
||||
// 状态代码的完整列表。
|
||||
switch (createStatus)
|
||||
{
|
||||
case MembershipCreateStatus.DuplicateUserName:
|
||||
return "用户名已存在。请另输入一个用户名。";
|
||||
|
||||
case MembershipCreateStatus.DuplicateEmail:
|
||||
return "已存在与该电子邮件地址对应的用户名。请另输入一个电子邮件地址。";
|
||||
|
||||
case MembershipCreateStatus.InvalidPassword:
|
||||
return "提供的密码无效。请输入有效的密码值。";
|
||||
|
||||
case MembershipCreateStatus.InvalidEmail:
|
||||
return "提供的电子邮件地址无效。请检查该值并重试。";
|
||||
|
||||
case MembershipCreateStatus.InvalidAnswer:
|
||||
return "提供的密码取回答案无效。请检查该值并重试。";
|
||||
|
||||
case MembershipCreateStatus.InvalidQuestion:
|
||||
return "提供的密码取回问题无效。请检查该值并重试。";
|
||||
|
||||
case MembershipCreateStatus.InvalidUserName:
|
||||
return "提供的用户名无效。请检查该值并重试。";
|
||||
|
||||
case MembershipCreateStatus.ProviderError:
|
||||
return "身份验证提供程序返回了错误。请验证您的输入并重试。如果问题仍然存在,请与系统管理员联系。";
|
||||
|
||||
case MembershipCreateStatus.UserRejected:
|
||||
return "已取消用户创建请求。请验证您的输入并重试。如果问题仍然存在,请与系统管理员联系。";
|
||||
|
||||
default:
|
||||
return "发生未知错误。请验证您的输入并重试。如果问题仍然存在,请与系统管理员联系。";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = true)]
|
||||
public sealed class PropertiesMustMatchAttribute : ValidationAttribute
|
||||
{
|
||||
private const string _defaultErrorMessage = "'{0}' 和 '{1}' 不匹配。";
|
||||
private readonly object _typeId = new object();
|
||||
|
||||
public PropertiesMustMatchAttribute(string originalProperty, string confirmProperty)
|
||||
: base(_defaultErrorMessage)
|
||||
{
|
||||
OriginalProperty = originalProperty;
|
||||
ConfirmProperty = confirmProperty;
|
||||
}
|
||||
|
||||
public string ConfirmProperty { get; private set; }
|
||||
public string OriginalProperty { get; private set; }
|
||||
|
||||
public override object TypeId
|
||||
{
|
||||
get
|
||||
{
|
||||
return _typeId;
|
||||
}
|
||||
}
|
||||
|
||||
public override string FormatErrorMessage(string name)
|
||||
{
|
||||
return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
|
||||
OriginalProperty, ConfirmProperty);
|
||||
}
|
||||
|
||||
public override bool IsValid(object value)
|
||||
{
|
||||
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(value);
|
||||
object originalValue = properties.Find(OriginalProperty, true /* ignoreCase */).GetValue(value);
|
||||
object confirmValue = properties.Find(ConfirmProperty, true /* ignoreCase */).GetValue(value);
|
||||
return Object.Equals(originalValue, confirmValue);
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
|
||||
public sealed class ValidatePasswordLengthAttribute : ValidationAttribute
|
||||
{
|
||||
private const string _defaultErrorMessage = "'{0}' 必须至少包含 {1} 个字符。";
|
||||
private readonly int _minCharacters = Membership.Provider.MinRequiredPasswordLength;
|
||||
|
||||
public ValidatePasswordLengthAttribute()
|
||||
: base(_defaultErrorMessage)
|
||||
{
|
||||
}
|
||||
|
||||
public override string FormatErrorMessage(string name)
|
||||
{
|
||||
return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
|
||||
name, _minCharacters);
|
||||
}
|
||||
|
||||
public override bool IsValid(object value)
|
||||
{
|
||||
string valueAsString = value as string;
|
||||
return (valueAsString != null && valueAsString.Length >= _minCharacters);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user