Base solution for your next web application

Activities of "SorenRomer"

We are at the latest version of AspNetZero and I am having trouble adding Ukrainian as a language for localization in the solution.

I have followed this guide (and successfully added other languages): https://aspnetboilerplate.com/Pages/Documents/Zero/Language-Management

I get this error when I try to select the language to be used:

I found the issue to be in one of the imported css files

Prerequisites

  • What is your product version? V11.0.0
  • What is your product type (Angular or MVC)? Angular
  • What is product framework type (.net framework or .net core)? .Net 6

If issue is about UI

I get this error message when I run npm run publish after I have updated to ANZ V11 from 10.5.0

If I upgrade Angular manually to 13.2.2 (latest) I get this error:

Is there any way I can get more details on this error?

Prerequisites

  • What is your product version? 10.5.0
  • What is your product type (Angular or MVC)? Angular
  • What is product framework type (.net framework or .net core)? .Net 5

If issue related with ABP Framework

  • What is ABP Framework version? 6.5.0

If issue is about UI

  • Which theme are you using? Default

Question

After the latest update to Asp.Net Zero 10.5.0 some events (maybe lazyload events) are not fired when the angular solution is deployed to a environment. It works locally when running angular in debug on localhost.

It is not a backend issue because if I connect the debug localhost instance of angular to the deployed backend it works perfectly.

The example in question is the Tenant impersonation. (We did not make any changes to this. ) It uses the CommonLookupModal and I have put some console log statements to reveal how it is called:

When run locally the getRecords method is called twice upon opening the modal. When run on the environment the getRecords method are only called once with the event value being null.

Hope you have some suggestions

I found issue - sort of.... If I avoid calling EventBus.Trigger(new CustomEvent { Id = user.Id}); the tenantId is reset to the correct value after the using is disposed. Calling await EventBus.TriggerAsync(new CustomEvent { Id = user.Id}); results in the same behaviour.

I don't understand this behaviour of the EventBus? Why does it stick to tenantid null when it is being called after the using is disposed?

Wrapping the call to the eventbus inside its own using solves the problem:

using (_unitOfWorkManager.Current.SetTenantId(AbpSession.GetTenantId()))
{
    await EventBus.TriggerAsync(new CustomEvent { Id = user.Id});
}

Hi @ismcagdas, Sure thing, I kept the DoCustomStuffAsync naming:

[UnitOfWork]
[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.GetUserByIdAsync(input.User.Id.Value);

    //Update user properties
    ObjectMapper.Map(input.User, user); //Passwords is not mapped (see mapping configuration)

    // CUSTOM CODE 
    // _unitOfWorkManager.Current.GetTenantId() is **1** at this point.
    if (input.AssignedCourseId != null && AbpSession.MultiTenancySide != Abp.MultiTenancy.MultiTenancySides.Host)
    {
        await DoCustomStuffAsync(input, user);
    }
     // _unitOfWorkManager.Current.GetTenantId() is **null** at this point.

    CheckErrors(await UserManager.UpdateAsync(user));

    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);
        CheckErrors(await UserManager.ChangePasswordAsync(user, input.User.Password));
    }

    //Update roles
    CheckErrors(await UserManager.SetRolesAsync(user, input.AssignedRoleNames));

    //update organization units
    await UserManager.SetOrganizationUnitsAsync(user, input.OrganizationUnits.ToArray());

    if (input.SendActivationEmail)
    {
        user.SetNewEmailConfirmationCode();
        await _userEmailer.SendEmailActivationLinkAsync(
            user,
            AppUrlService.CreateEmailActivationUrlFormat(AbpSession.TenantId),
            input.User.Password
        );
    }
}

Here is a simplified version of the custom method:

[UnitOfWork]
private async Task DoCustomStuffAsync(CreateOrUpdateUserInput input, User user)
{
    if (input.CustomEnityId != null)
    {
        using (_unitOfWorkManager.Current.SetTenantId(null))
        {
        // GETTING GENERAL DATA FROM HOST
            var _customEntities = _customEntityRepository.GetAllIncluding(c => c.CourseFlows).FirstOrDefault(c => c.Id == (int)input.AssignedCourseId);

        // CODE REMOVED FOR CLARITY
        }

        EventBus.Trigger(new CustomEvent { Id = user.Id});
    }
    else
    {
        Logger.Info($"User {user.UserName} is not assigned to a custom entity");
    }
}

Thanks in advance

Prerequisites

Please answer the following questions before submitting an issue. YOU MAY DELETE THE PREREQUISITES SECTION.

  • What is your product version?
    • 10.3
  • What is your product type (Angular or MVC)?
    • Angular
  • What is product framework type (.net framework or .net core)?
    • .Net core

If issue related with ABP Framework

  • What is ABP Framework version?
    • 6.3

Multitenancy ENABLED

Question

I have a strange issue in the UserAppService class.

I have added a new custom property to the User class that needs to get set during update and creation of users. The issue is that in order to assign the right values for the custom property I need to get some data from the database created by the host. To avoid too much polution of the create and update user methods I have extracted the functionality to a private async method inside the UserAppService class.

While entering UpdateUserAsync() _unitOfWorkManager.Current.GetTenantId() returns the correct tenantId but after my private method is called the same statement returns null.

This is what I have done inside the private method: Attempt #1 Assuming tenant ID will be reset to AbpSession.GetTenantId() value after using is complete (it is not)

private async Task DoCustomStuffAsync(CreateOrUpdateUserInput input, User user)
{
    if(user.CustomProp == null)
        return;
        
     using (_unitOfWorkManager.Current.SetTenantId(null))
    {
        // Getting host data *** WORKS
    }
}

Attempt #2 forcing new UOW

private async Task DoCustomStuffAsync(CreateOrUpdateUserInput input, User user)
{
    if(user.CustomProp == null)
        return;
    
    using(var uow = _unitOfWorkManager.Begin())
    using (_unitOfWorkManager.Current.SetTenantId(null))
    {
        // Getting host data *** WORKS
        
        uow.Complete();
    }
}

Attempt #2 Forcing new transaction scope

private async Task DoCustomStuffAsync(CreateOrUpdateUserInput input, User user)
{
    if(user.CustomProp == null)
        return;
    
    using(var uow = _unitOfWorkManager.Begin(RequiresNew))
    using (_unitOfWorkManager.Current.SetTenantId(null))
    {
        // Getting host data *** WORKS
        
        uow.Complete();
    }
}

Attempt #3 Manual dispose of uow scope

private async Task DoCustomStuffAsync(CreateOrUpdateUserInput input, User user)
{
    if(user.CustomProp == null)
        return;
    
    using(_unitOfWorkManager.Begin())
    using (var uow = _unitOfWorkManager.Current.SetTenantId(null))
    {
        // Getting host data *** WORKS
        
        uow.Dispose(); //Should not be nessesary
    }
}

Attempt #4 Marking methods (and class) with UOW

[UnitOfWork]
public async Task UpdateUserAsync(....)

[UnitOfWork]
private async Task DoCustomStuffAsync(CreateOrUpdateUserInput input, User user)
{
    if(user.CustomProp == null)
        return;
    
    using (var uow = _unitOfWorkManager.Current.SetTenantId(null))
    {
        // Getting host data *** WORKS
    }
}

What am I doing wrong here? I can obviously set the tenantID again in the UpdateUserAsync method but that is not a good way IMO.

Best regards

Showing 1 to 7 of 7 entries