Cri*_*lho 6 asp.net-mvc asp.net-membership asp.net-mvc-4 simplemembership
我需要一个关于该怎么做的建议.我目前正在使用WebSecurity方法来完成所有与帐户相关的工作.但它不支持电子邮件唯一性验证,所以我有几个选择:
编写(子类)新的SimpleMembershipProvider,覆盖现有的createuserAndAccount方法以验证电子邮件地址.但我还必须实现登录注销功能(就像websecurity一样)和其他一些功能.
在数据库上添加唯一性约束并在我的代码上捕获它们.但是这会导致我依赖于数据库.
这可能有点便宜,但我可以将WebSecurity源代码(自打开以来)复制/粘贴到新类上,并修改createUserAndAccount方法.
还有其他选择吗?我目前的目标是选择3,这将是最快的方式.另外,关于未来我也将要求角色,我不确定WebSecurity是否为它们提供支持.
如果是我,我可能会采取以下方式:
首先,假设您正在使用SimpleMembership与Entity Framework或某些数据库连接(ADO,LINQ to SQL等),您将拥有两个组件:WebSecurity.*方法调用和数据库连接以进行配置文件更改.就个人而言,我会将CONSTRAINT数据库添加到数据库以确保您的数据是纯粹的,但您也可以实现处理此逻辑的成员资格服务.
首先,将这些组合到一个可以在控制器中引用的接口(如下所示):
public interface IMembershipService
{
Int32 CurrentUserId { get; }
String CurrentUserName { get; }
Boolean IsAuthenticated { get; }
Boolean CreateUserAndAccount(String username, String password, String emailaddress = null);
Boolean CreateUserAndAccount(String username, string password, out String confirmationToken, String emailaddress = null);
Boolean Login(String username, String password, Boolean persistCookie = false);
void Logout();
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以将服务实现为SimpleMembership和数据库连接的混合体.为了保持其通用的缘故,我用的IRepository<T>模式,但是这可能是直接的DbContext,ObjectContext等我也保持它的简单,所以借口失踪校验和短期实现.
public class MembershipService : IMembershipService
{
protected readonly SimpleMembershipProvider membershiProvider;
protected readonly SimpleRoleProvider roleProvider;
protected readonly IRepository<UserProfile> profileRepository;
public MembershipService(IRepository<UserProfile> profileRepository)
{
this.membershipProvider = Membership.Provider as SimpleMembershipProvider;
this.roleProvider = Role.Provider as SimpleRoleProvider;
this.profileRepository = userRepository;
}
#region IMembershipService Implementation
public Int32 CurrentUserId
{
get { return WebSecurity.CurrentUserId; }
}
public String CurrentUserName
{
get { return WebSecurity.CurrentUserName; }
}
public Boolean IsAuthenticated
{
get { return WebSecurity.IsAuthenticated; }
}
public Boolean CreateUserAndAccount(String username, String password, String emailaddress = null)
{
// validate the email address is unique
if (!this.profileRepository.Any(x => x.EmailAddress == emailaddress))
{
WebSecurity.CreateUserAndAccount(username, password, new
{
EmailAddress = emailaddress
}, createConfirmationToken);
return true;
}
else
{
// handle the error how you see fit
// (maybe even exception?)
return false;
}
}
public Boolean CreateUserAndAccount(String username, String password, out String confirmationToken, String emailaddress = null, out)
{
// validate the email address is unique
if (this.profileRepository.First(x => x.EmailAddress == emailaddress) == null)
{
confirmationToken = WebSecurity.CreateUserAndAccount(username, password, new
{
EmailAddress = emailaddress
}, createConfirmationToken);
return true;
}
else
{
// handle the error how you see fit
// (maybe even exception?)
confirmationToken = String.Empty;
return false;
}
}
public Boolean Login(String username, String password, Boolean persistCookie = false)
{
return WebSecurity.Login(username, password, persistCookie);
}
public void Logout()
{
WebSecurity.Logout();
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
现在,您可以在控制器中引用此接口,并将逻辑放在一个位置.如果你正在使用DI容器,显然要注册它,但这是一个示例实现:
public class AccountController: Controller
{
private readonly IMembershipService membershipService;
public AccountController(IMembershipService membershipService)
{
this.membershipService = membershipService;
}
/* ... */
[HttpPost, ValidateAntiForgeryToken]
public ActionResult Register(LoginViewModel model, String returnUrl)
{
if (ModelState.IsValid)
{
if (this.membershipService.CreateUserandAccount(model.Username, model.Password, model.EmailAddress))
{
this.membershipService.Login(model.Username, model.Password);
if (!String.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
return RedirectToRoute("Default");
}
else
{
ModelState.AddModelError("", "Unable to register.");
}
}
return View(model);
}
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
如果您正在使用EntityFramework,您也可以使用IValidatableObject.为了抵制重复,这是另一个检查唯一条目的SO问题/答案:
| 归档时间: |
|
| 查看次数: |
5883 次 |
| 最近记录: |