The problem is solved if I use this editted code. Is this a bug or am I doing something wrong?
[AbpAuthorize(AppPermissions.Pages_Administration_Users_Edit)]
protected virtual async Task UpdateUserAsync(CreateOrUpdateUserInput input)
{
Debug.Assert(input.User.Id != null, "input.User.Id should be set.");
var user = await UserManager.FindByIdAsync(input.User.Id.Value);
//////// THIS VARIABLE IS NEW
var originalPassword = user.Password;
//Update user properties
input.User.MapTo(user); //Passwords is not mapped (see mapping configuration)
if (input.SetRandomPassword)
{
input.User.Password = User.CreateRandomPassword();
}
//////// THE 'ELSE' KEYWORD IS NEW
else if (!input.User.Password.IsNullOrEmpty())
{
CheckErrors(await UserManager.ChangePasswordAsync(user, input.User.Password));
}
//////// THIS ELSE BLOCK IS NEW
else
{
user.Password = originalPassword;
}
CheckErrors(await UserManager.UpdateAsync(user));
//Update roles
CheckErrors(await UserManager.SetRoles(user, input.AssignedRoleNames));
if (input.SendActivationEmail)
{
user.SetNewEmailConfirmationCode();
await _userEmailer.SendEmailActivationLinkAsync(user, input.User.Password);
}
}
Apologies, it is executed. The debugger does not hit the break points but I have added some log statements and these get written to the log file. For example:
DEBUG 2017-10-04 15:46:06,130 [25 ] CustomDtoMapper - Entered method CreateMappingsInternal
The CustomDtoMapper does not appear to be executed.
It definitely maps. Here is my current code for reference:
protected virtual async Task UpdateUserAsync(CreateOrUpdateUserInput input)
{
Debug.Assert(input.User.Id != null, "input.User.Id should be set.");
var user = await UserManager.FindByIdAsync(input.User.Id.Value);
//var originalPassword = user.Password;
//Update user properties
//input.User.MapTo(user); //Passwords is not mapped (see mapping configuration)
////////// PROVIDE A FAKE PASSWORD AND SEE IF IT MAPS
input.User.Password = "ThisIsFake-WillItMap";
//////////CODE SUGGESTED BY ARRON
ObjectMapper.Map(input.User, user);
//////////BREAKPOINT HERE AND REVIEW
Debug.Assert(user.Password.Equals(input.User.Password), "Password did not map.");
if (input.SetRandomPassword)
{
input.User.Password = User.CreateRandomPassword();
}
if (!input.User.Password.IsNullOrEmpty())
{
CheckErrors(await UserManager.ChangePasswordAsync(user, input.User.Password));
}
//else
//{
// user.Password = originalPassword;
//}
CheckErrors(await UserManager.UpdateAsync(user));
//Update roles
CheckErrors(await UserManager.SetRoles(user, input.AssignedRoleNames));
if (input.SendActivationEmail)
{
user.SetNewEmailConfirmationCode();
await _userEmailer.SendEmailActivationLinkAsync(user, input.User.Password);
}
}
HI Arron,
yes I tried it in my debugger. Using your method does map the password. I will double check now though.
HI Arron,
thank you for your reply, but unfortunately your suggestion does not work.
If I only change the roles a user belongs to, the form input data that is sent to the user service does not contain a password (the password is an empty string). Therefore, even though using the ObjectMapper.Map function will map the password field, it maps the empty string, and so the EntityFramework update fails.
I have fixed this by editting the UserAppService, method UpdateUserAsync. But I can't help thinking I am missing something and I didn't need to change such a fundamental part of the system. Here is my change - I welcome any comments.
[AbpAuthorize(AppPermissions.Pages_Administration_Users_Edit)]
protected virtual async Task UpdateUserAsync(CreateOrUpdateUserInput input)
{
Debug.Assert(input.User.Id != null, "input.User.Id should be set.");
var user = await UserManager.FindByIdAsync(input.User.Id.Value);
//////// THIS VARIABLE IS NEW
var originalPassword = user.Password;
//Update user properties
input.User.MapTo(user); //Passwords is not mapped (see mapping configuration)
if (input.SetRandomPassword)
{
input.User.Password = User.CreateRandomPassword();
}
//////// THE 'ELSE' KEYWORD IS NEW
else if (!input.User.Password.IsNullOrEmpty())
{
CheckErrors(await UserManager.ChangePasswordAsync(user, input.User.Password));
}
//////// THIS ELSE BLOCK IS NEW
else
{
user.Password = originalPassword;
}
CheckErrors(await UserManager.UpdateAsync(user));
//Update roles
CheckErrors(await UserManager.SetRoles(user, input.AssignedRoleNames));
if (input.SendActivationEmail)
{
user.SetNewEmailConfirmationCode();
await _userEmailer.SendEmailActivationLinkAsync(user, input.User.Password);
}
}
Perhaps a better way to phrase my question.
In order to change a users roles using ABP Zero, I have to change the password at the same time. I just want to be able to change the assigned roles without changing the password. Is this possible?
Hi Aaron, that was exactly the information I was looking for! Thank you.
Issue created -- customErrors and httpErrors Conflict #533