Base solution for your next web application
Starts in:
01 DAYS
01 HRS
01 MIN
01 SEC

Activities of "tusksoft"

Thank you for the direction. Unfortunately edition is a relatively simple compared to User where there is substantially more process around it. I have marked below in the original User creation method from UserAppService.cs at the start of every block that will be duplicated in a create method on StaffMember with ///DUPLICATED to indicate the level of duplication im concerned about.

[AbpAuthorize(AppPermissions.Pages_Administration_Users_Create)]
protected virtual async Task CreateUserAsync(CreateOrUpdateUserInput<UserEditDto> input)
{
    ///DUPLICATED
    if (AbpSession.TenantId.HasValue)
    {
        await _userPolicy.CheckMaxUserCountAsync(AbpSession.GetTenantId());
    }

    /// This will be different because we have to use custom mappings
    var user = ObjectMapper.Map<User>(input.User); //Passwords is not mapped (see mapping configuration)
    user.TenantId = AbpSession.TenantId;

    ///DUPLICATED
    //Set password
    if (input.SetRandomPassword)
    {
        var randomPassword = await _userManager.CreateRandomPassword();
        user.Password = _passwordHasher.HashPassword(user, randomPassword);
        input.User.Password = randomPassword;
    }
    else if (!input.User.Password.IsNullOrEmpty())
    {
        await UserManager.InitializeOptionsAsync(AbpSession.TenantId);
        foreach (var validator in _passwordValidators)
        {
            CheckErrors(await validator.ValidateAsync(UserManager, user, input.User.Password));
        }

        user.Password = _passwordHasher.HashPassword(user, input.User.Password);
    }

    ///DUPLICATED
    user.ShouldChangePasswordOnNextLogin = input.User.ShouldChangePasswordOnNextLogin;

    ///DUPLICATED (with minor changes if our derived users end up having dedicated roles)
    //Assign roles
    user.Roles = new Collection<UserRole>();
    foreach (var roleName in input.AssignedRoleNames)
    {
        var role = await _roleManager.GetRoleByNameAsync(roleName);
        user.Roles.Add(new UserRole(AbpSession.TenantId, user.Id, role.Id));
    }

    ///DUPLICATED
    CheckErrors(await UserManager.CreateAsync(user));
    await CurrentUnitOfWork.SaveChangesAsync(); //To get new user's Id.

    ///DUPLICATED (I can see a reason this wouldnt be duplicated for some subclassed users)
    //Notifications
    await _notificationSubscriptionManager.SubscribeToAllAvailableNotificationsAsync(user.ToUserIdentifier());
    await _appNotifier.WelcomeToTheApplicationAsync(user);

    ///DUPLICATED (I can see a reason this wouldnt be duplicated for some subclassed users)
    //Organization Units
    await UserManager.SetOrganizationUnitsAsync(user, input.OrganizationUnits.ToArray());

    ///DUPLICATED (I can see a reason this wouldnt be duplicated for some subclassed users)
    //Send activation email
    if (input.SendActivationEmail)
    {
        user.SetNewEmailConfirmationCode();
        await _userEmailer.SendEmailActivationLinkAsync(
            user,
            AppUrlService.CreateEmailActivationUrlFormat(AbpSession.TenantId),
            input.User.Password
        );
    }
}

That is just for one method in the UserAppService. So if there are updates to the framework, I'm worried that unless we go through the diffs we would miss those updates (because we aren't subclassing the service, it could go completely unnoticed)

Maybe this is unavoidable, but I'm just worried that there is a code-smell here where subclassing involves duplication a lot of code. Was AspNetZero/ABP built with subclassing User as a supported pattern? It seems like some of this behavior could be consolidated or handled by events. (That would make creating services for subclassed users a much smaller undertaking without worrying about losing other behaviours like notifications or welcome emails because they were overlooked)

I think the solution proposed will work for us, I just want to be absolutely certain before I develop our subclassed user app services such that they are detached from the original UserAppService as that will be a non-trivial time sink.

Yes, it can be reproduced in the demo project. In a pristine solution just run add-migration followed by remove-migration . You can actually skip adding the empty migration and just run remove-migration to achieve the same exception.

We've had to nuke ALL of the migrations that come with A0 and recreate them as a single migration in order to get things working properly. We're avoiding committing this change as it will create additional pain when upgrading the A0 framework.

In the github issue I linked to the problem was reported fixed, but the use case here does not seem to be covered by the fix. I would venture to guess that if the SQL Server column types were explicitly defined in the cs.designer files all would work as expected, but that requires a prohibitive time investment on our end and presents the same problem in terms of upgradability. This is something your team would need to do to maintain maximum upgradability of the framework.

One final note, I've tried to recreate this problem in a VS2019 templated project with no success. These were the steps I used:

  1. Create project
  2. nuke templated migrations
  3. roll back EF related packages to 2.x versions and update context code as necessary to be able to run add-migration successfully (see https://stackoverflow.com/questions/45782446/unable-to-create-migrations-after-upgrading-to-asp-net-core-2-0)
  4. add an initial migration
  5. update EF packages to 3.1.x
  6. run add-migration
  7. run remove-migration

I have been unable to reproduce in a templated app. I can, however, reproduce in a pristine copy of A0 8.0.0. Could you or I provide a copy to their team behind auth challenge and share credentials privately? A demo app would be sufficient.

This bug is having a pretty severe affect on our workflow for an application we've just started working on so we really need to get this addressed. I'm not sure how to work around it in A0, and A0 is the only app we have that's exhibiting this behavior. If you all can find a workaround, we're fine with that as well. We just need it fixed for 8.0.0 to be a viable platform for us to move forward with.

Yes, using single solution. Since it's pointing towards MVC directories in the gitignore we're guessing at which files should be excluded based on a previous project that used A0 5.x.

Dead link on the github discussion.

Showing 21 to 25 of 25 entries