I want to move my members from the umbraco database to another database, where the members will be stored. I need to implement my own membership provider, as I want to hash everything we know about our users.
Untill now I have just been trying to very simple membership provider to store some mock users in a local database. I have so far based my solution on an earlier post (https://our.umbraco.com/forum/developers/extending-umbraco/74219-custom-membership-provider/), however I am using the Entity framework instead.
So far I have
Created a custom membership provider inheriting from the standard membership provider.
Made a member repository with methods for interactions with the database.
Made a model class with an entity framework class.
Replaced the default umbraco membership provider with my custom membership provider in the Web.config file.
When I try to create a member in the backoffice -> Members -> Members -> create I get an error message. To me it seems that Umbraco doesn't recognize my membership provider. I hope someone out there is able to helpt me, I've been stuck with this for quite some time now.
Error message
System.NullReferenceException: Object reference not set to an instance of an object.
Stacktrace
at Umbraco.Web.Models.Mapping.MemberTabsAndPropertiesMapper.Map(IMember source, MapperContext context)
at Umbraco.Web.Models.Mapping.MemberMapDefinition.Map(IMember source, MemberDisplay target, MapperContext context)
at Umbraco.Core.Mapping.UmbracoMapper.<>c_DisplayClass802.<Define>b__1(Object source, Object target, MapperContext context)
at Umbraco.Core.Mapping.UmbracoMapper.Map[TTarget](Object source, Type sourceType, MapperContext context)
at Umbraco.Core.Mapping.UmbracoMapper.Map[TTarget](Object source, MapperContext context)
at Umbraco.Web.Editors.MemberController.GetEmpty(String contentTypeAlias)
at lambda_method(Closure , Object , Object[] )
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass6_2.<GetExecutor>b__2(Object instance, Object[] methodParameters)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)
at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary2 arguments, CancellationToken cancellationToken)
My code
CustomMemberhipProvider.cs
public class CustomMembershipProvider : MembershipProvider
{
private string _applicationName = "UmbracoMembershipProvider";
public override string ApplicationName {
get { return _applicationName; }
set
{
if (string.IsNullOrEmpty(value))
throw new ProviderException("ApplicationName cannot be empty");
if (value.Length > 0x100)
throw new ProviderException("Provider application name too long");
_applicationName = value;
}
}
public override void Initialize(string name, NameValueCollection config)
{
base.Initialize(name, config);
}
public override bool EnablePasswordRetrieval => false;
public override bool EnablePasswordReset => false;
public override bool RequiresQuestionAndAnswer => false;
public override int MaxInvalidPasswordAttempts => throw new NotImplementedException();
public override int PasswordAttemptWindow => throw new NotImplementedException();
public override bool RequiresUniqueEmail => true;
public override MembershipPasswordFormat PasswordFormat => MembershipPasswordFormat.Hashed;
public override int MinRequiredPasswordLength => 6;
public override int MinRequiredNonAlphanumericCharacters => 0;
public override string PasswordStrengthRegularExpression => throw new NotImplementedException();
public override bool ChangePassword(string username, string oldPassword, string newPassword)
{
throw new NotImplementedException();
}
public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
{
throw new NotImplementedException();
}
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
{
var memberRepository = new MembersRepository();
bool memberCreated = memberRepository.CreateUser(username, email, password);
MembershipUser newMember = new MembershipUser(
"UmbracoMembershipProvider",
username,
providerUserKey,
email,
passwordQuestion,
"",
isApproved,
false,
DateTime.Now,
DateTime.Now,
DateTime.Now,
DateTime.Now,
DateTime.Now
);
if( memberCreated)
{
status = MembershipCreateStatus.Success;
return newMember;
}
status = MembershipCreateStatus.ProviderError;
return null;
}
public override bool DeleteUser(string username, bool deleteAllRelatedData)
{
var memberRepository = new MembersRepository();
return memberRepository.DeleteUser(username);
}
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
{
throw new NotImplementedException();
}
public override int GetNumberOfUsersOnline()
{
throw new NotImplementedException();
}
public override string GetPassword(string username, string answer)
{
throw new NotImplementedException();
}
public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
{
var repos = new MembersRepository();
MockUserClass member = repos.GetUserById( (Guid)providerUserKey );
if (member != null)
return ConvertToMembershipUser(member);
return null;
}
public override MembershipUser GetUser(string username, bool userIsOnline)
{
var repos = new MembersRepository();
var member = repos.GetUserByName(username);
if (member != null)
{
return ConvertToMembershipUser(member);
}
return null;
}
public override string GetUserNameByEmail(string email)
{
var repos = new MembersRepository();
return repos.GetUserNameByEmail(email);
}
public override string ResetPassword(string username, string answer)
{
throw new NotImplementedException();
}
public override bool UnlockUser(string userName)
{
throw new NotImplementedException();
}
public override void UpdateUser(MembershipUser user)
{
throw new NotImplementedException();
}
public override bool ValidateUser(string username, string password)
{
var repos = new MembersRepository();
MockUserClass member = repos.GetUserByName(username);
if(member != null)
{
if (member.Password == password)
return true;
}
return false;
}
private MembershipUser ConvertToMembershipUser(MockUserClass member)
{
return new MembershipUser("UmbracoMembershipProvider", member.Username, member.Id, member.Email, "", "", member.IsApproved, member.IsLockedOut, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.MinValue, DateTime.MinValue);
}
private MembershipUserCollection GetMembershipUserCollection(IEnumerable<MockUserClass> queryResult)
{
var Members = new MembershipUserCollection();
foreach (var member in queryResult)
{
Members.Add(ConvertToMembershipUser(member));
}
return Members;
}
}
MembersRepository.cs
public class MembersRepository
{
public bool CreateUser(string username,string email, string password)
{
using (var context = new UserDb())
{
var newMember = new MockUserClass(
username,
password,
email
);
context.Members.Add(newMember);
return true;
};
}
public bool DeleteUser(string username)
{
using (var context = new UserDb())
{
var member = (from m in context.Members
where m.Username == username
select m).FirstOrDefault();
if (member != null)
{
context.Members.Remove(member);
return true;
}
return false;
}
}
public MockUserClass GetUserById(Guid id)
{
using (var context = new UserDb())
{
var member = (from m in context.Members
where m.Id == id
select m).FirstOrDefault();
return member;
}
}
public MockUserClass GetUserByName(string name)
{
using (var context = new UserDb())
{
var member = (from m in context.Members
where m.Username == name
select m).FirstOrDefault();
return member;
}
}
public string GetUserNameByEmail(string email)
{
using (var context = new UserDb())
{
var username = (from member in context.Members
where member.Email == email
select member.Username).FirstOrDefault();
return username;
}
}
}
Entity framework class
public class UserDb : DbContext
{
public UserDb():base("name=UserDb"){}
public DbSet<MockUserClass> Members { get; set; }
}
Hi, do you still remember how exactly you solved the problem?
I.ve implemented the IMember interface but that hasn't worked anyway.
An example code would be much appreciated.
Thank you.
Custom membership provider in Umbraco 8
Hello Umbracoland
I want to move my members from the umbraco database to another database, where the members will be stored. I need to implement my own membership provider, as I want to hash everything we know about our users.
Untill now I have just been trying to very simple membership provider to store some mock users in a local database. I have so far based my solution on an earlier post (https://our.umbraco.com/forum/developers/extending-umbraco/74219-custom-membership-provider/), however I am using the Entity framework instead.
So far I have
When I try to create a member in the backoffice -> Members -> Members -> create I get an error message. To me it seems that Umbraco doesn't recognize my membership provider. I hope someone out there is able to helpt me, I've been stuck with this for quite some time now.
Error message
Stacktrace
My code
CustomMemberhipProvider.cs
MembersRepository.cs
Entity framework class
Snippets from web.config
Hi Johan what does your MockUserClass look like? Does it implement the IMember interface which the Umbraco mapper looks to be expecting?
Hi Ian
No it does not! I will try to implement it and return with a result.
I think this has solved my problem, now I just need to figure out what to implement! thank you so much!
Hi, do you still remember how exactly you solved the problem? I.ve implemented the IMember interface but that hasn't worked anyway. An example code would be much appreciated. Thank you.
I am looking to do something similar. Appreciate if there's any sharing on this. thanks
is working on a reply...