问题
Continue from this solution : How to configure Ninject for MVC4 & custom Membership provide?
I declare
public interface IUserRepository : IRepository<UserModel>
{
MembershipUser CreateUser(string username, ... , string providername = null);
void Logout();
Boolean Login(string userName, string Password, bool persistCookie = false);
bool RegisterUser(UserModel user);
}
And implement within UserRepository
public class UserRepository : RepositoryBase<MyDbContext, UserModel>, IUserRepository
{
UserModel _user = null;
public UserRepository(IUnitOfWork<MyDbContext> unitOfWork)
: base(unitOfWork)
{
}
public MembershipUser CreateUser(string username, ... , string providername = null)
{
using (UnitOfWork)
{
_user = new UserModel
{
Id = Guid.NewGuid(),
RoleId = roleId
[other property set]
};
Insert(_user);
UnitOfWork.Commit();
}
status = MembershipCreateStatus.Success;
return new MembershipUser(providername, ...);
}
public bool RegisterUser(UserModel user)
{
MembershipCreateStatus createStatus;
CreateUser(user.UserName, user.Password, user.Email, user.PasswordQuestion, user.PasswordAnswer, user.IsApproved, null, out createStatus, ...);
if (createStatus == MembershipCreateStatus.Success)
{
return true;
}
else
{ return false;
}
}
[..]
Now within CustomMembership Provider
public class CustomMembershipProvider : MembershipProvider
{
public IUserRepository UserRepository { get { return DependencyResolver.Current.GetService<IUserRepository>(); } }
public override MembershipUser CreateUser(string username, ...)
{
return UserRepository.CreateUser(username, password, email, passwordQuestion, passwordAnswer, isApproved, providerUserKey, out status, Membership.Provider.Name);
}
[...]
Now within Controller
public AccountController(IAccountRepository accountRepository, IUserRepository userRepository, IUnitOfWork<MyDbContext> unitOfWork)
{
_acountRepository = accountRepository;
_userRepository = userRepository;
UnitOfWork = unitOfWork;
}
public ActionResult Register(UserModel model)
{
if (ModelState.IsValid)
{
_userRepository.RegisterUser(model);
}
}
Note:
1. I got the Error Provider name is Null from UserRepository CreateUser method from this line return new MembershipUser(providername,...);
.
But I already pass it as Membership.Provider.Name
within customMembership provider.
2. What is the proper way to call Membershipprovider method from Controller ?
3. Is the any other Ninject configuration required to call Membership provider method via IUserRepository, other that bellow ?
kernel.Bind<IUserRepository>().To<UserRepository>();
4. Web.config as previous post
回答1:
So, you have CustomMembershipProvider.CreateUser and UserRepository.CreateUser. Your controller is directly calling UserRepository.CreateUser but I think you really want to call CustomMembershipProvider.CreateUser?
Your Controller is calling
public bool RegisterUser(UserModel user)
{
MembershipCreateStatus createStatus;
CreateUser(user.UserName, user.Password, user.Email, user.PasswordQuestion, user.PasswordAnswer, user.IsApproved, null, out createStatus, ...);
which in turn is calling
public MembershipUser CreateUser(string username, ... , string providername = null)
but, as far as I can tell, you are passing a NULL for the provider name.
What you really want to split this up a bit more into a MembershipService which you can inject into your controllers.
I can't give you a simple "change this line" answer, the problem is conceptual, sorry. You could pass a hard-coded providername but then you really do start to violate everything.
回答2:
In Web.Config something like this.... You tell Membership provider with provider to use. In this case your custom provider. But im not sure why ninject plays a role in this concept, so cant help with that aspect sorry. The customer provider MUST know its own name. But hardly an Issue. The Web.config has the name of the custom provider. So config not hard coded.
<membership defaultProvider="YourProvider" userIsOnlineTimeWindow="5">
<providers>
<!--attribute names in camelCase version of .net class MembershipProvider Properties. http://msdn.microsoft.com/en-us/library/system.web.security.membership_properties
See BOS class for constants : BOSSysConst
type = Implmenting provider class namespace.Classname
How to configure membership providers... http://msdn.microsoft.com/en-us/library/6e9y4s5t -->
<add name="YourProvider"
type="YourNamespace.YourProvider"
connectionStringName="YourConnectionString"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="true"
passwordFormat="Hashed"
applicationName="IMPORTANT" />
</providers>
</membership>
The Controller calls the static class for createUser Membership.CreateUser or Membership.ValidateUser to logon.
For details on implmenting a custom provider see http://msdn.microsoft.com/en-us/library/44w5aswa%28v=vs.100%29.aspx
// Sample calling the create user function
// POST: /Account/Register
[AllowAnonymous]
[HttpPost]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
// Attempt to register the user
MembershipCreateStatus createStatus;
Membership.CreateUser(model.UserName, model.Password, model.Email, passwordQuestion: null, passwordAnswer: null, isApproved: true, providerUserKey: null, status: out createStatus);
if (createStatus == MembershipCreateStatus.Success)
{
FormsAuthentication.SetAuthCookie(model.UserName, createPersistentCookie: false);
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("", ErrorCodeToString(createStatus));
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
来源:https://stackoverflow.com/questions/14425236/custom-membership-provider-mvc-4