Base solution for your next web application

Activities of "tom.ohle"

Just a general question about the Asp.Net Zero template projects.

Why do you use .Net Standard (netstandard2.0) for the (ProjectName).Application.Shared and (ProjectName).Core.Shared projects instead of .Net Core (netcoreapp3.1)? All the other projects like (ProjectName).Core are using .Net Core (netcoreapp3.1). We were thinking about updating these to .Net Core but didn't know if there was a reason we shouldn't.

We are using the ASP.NET Zero template version 9.0.1. How do you go about sorting child entites when they are retrieved using the GetAllIncluding method? According to the Microsoft documentation we should be able to do the following. https://docs.microsoft.com/en-us/ef/core/querying/related-data#filtered-include.

return await _entityRepository.GetAllIncluding( e => e.childEntities .OrderBy( ce => ce.childProperty) ) .ToListAsync();

I would normally submit this as a pull request, but alas...

I have an AbpODataEntityController and I want to add a custom FilterBcEnableQueryAttribute on the Get class. However, I cannot figure out how to implement dependency injection in the FilterBcEnableQueryAttribute class. How could I get an instantiated version of my IPermissionPolicyManager class, for example?

` public class WipsSearchController : AbpODataEntityController<WipSearch, long>, ITransientDependency {

    public WipsSearchController(IRepository<WipSearch, long> repository) : base(repository) 
    {
    }
    
    
    [DontWrapResult]
    //compile error here since no empty constructor; if I add empty constructor, the dependencies are not initialized
    [FilterBcEnableQuery]
    [AbpMvcAuthorize(AppPermissions.BusinessRule_Wips_View)] 
    public IQueryable<WipSearch> Get()
    {
        return base.Get();
    }
}

public class FilterBcEnableQueryAttribute : EnableQueryAttribute, ITransientDependency
{
    private readonly IPermissionPolicyManager _permissionPolicyManager;
    private readonly IWipBcPolicyHandler _wipBcPolicyHandler;


    public FilterBcEnableQueryAttribute(IPermissionPolicyManager permissionPolicyManager,
        IWipBcPolicyHandler wipBcPolicyHandler)
    {           
        _permissionPolicyManager = permissionPolicyManager;
        _wipBcPolicyHandler = wipBcPolicyHandler;
    }

    public override void OnActionExecuted(ActionExecutedContext actionExecutedContext)
    {
        base.OnActionExecuted(actionExecutedContext);
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        var args = context.HttpContext.ODataFeature();
        var bcOrgIds = new List<long>();
        var userPolicies = _permissionPolicyManager.GetUserPermissionPolicies(AppPermissions.BusinessRule_Wips_View);
        var bcUserPolicies = userPolicies.Where(p => p.PolicyName == AppPolicies.Wips_Bcs).ToList();
        
        var request = context.HttpContext.Request;
        var url = context.HttpContext.Request.GetEncodedUrl();
        if (url.IndexOf("$filter") == -1)
        {
            context.Result = new RedirectResult("http://localhost:22742/odata/wipssearch?$filter=BcNumber%20eq%20'1609'");
        }
        
        base.OnActionExecuting(context);
    }

} }`

The RoleAppService.DeleteRole method takes a very long time when the role to be deleted is currently assigned to a large number of users. In my case it is assigned to 20,000 users, and the call that takes the longest is UserManager.RemoveFromRoleAsync as you can see in the screenshot below.

It seems like the call to UserManager.RemoveFromRoleAsync decreases in performance when there are more than a small number of users assigned to the role (ie. the performance is drastically better when less than a hundred users are assigned).

Is this a known issue? Is there a recommended approach for working around this issue, or should I start thinking about how to come up with my own solution?

This behavior can be reproduced by dropping the following method into an application service in a brand new ASP.NET Zero 8.7.0 project (ASP.NET Core & Angular).

public void CreateTestUsers()
{
    // create 20000 test users
    
    var context = CurrentUnitOfWork.GetDbContext<MyDbContext>();
    
    for (var i = 0; i < 20000; ++i)
    {
        var first = $@"first{i}";
        var last = $@"last{i}";
        var userName = $@"{first}.{last}";
        var emailAddress = $@"{userName}@dummy.com";
        
        var user = new User
        {
            EmailAddress = emailAddress,
            IsEmailConfirmed = true,
            Name = first,
            Surname = last,
            UserName = userName,
            Password = "AM4OLBpptxBYmM79lGOX9egzZk3vIQU3d/gFCJzaBjAPXzYIK3tQ2N7X4fcrHtElTw==", //123qwe
            TenantId = 1,
        };

        user.SetNormalizedNames();
        context.Users.Add(user);
    }
    
    context.SaveChanges();
    
    // assign users to test role
    
    var userIds = context.Users.Select(user => user.Id).ToList();
    
    foreach (var userId in userIds)
    {
        context.UserRoles.Add(new UserRole
        {
            RoleId = 6,
            UserId = userId,
            TenantId = 1,
            CreationTime = DateTime.Now,
            CreatorUserId = 1,
        });
    }
    
    context.SaveChanges();
}

Thanks for reading!

Question

We are looking into using a shared redis cache server between several aspnetzero applications. We would be using a microservice to update some of the cache values so the information would remain the same for all of these applications.

The issue we're seeing with this approach is that each aspnetzero application uses a standard cache names for certain things ie (AbpZeroUserPermission, AbpZeroRolePermissions, AbpZeroLanguages, etc..)

Is there a way to alter these cache names or override them in some manner to give them a prefix of some sort so they would be unique accross all applications that would share the cache?

This behavior is exhibited by a brand new instance of a 8.7.0 ASP.NET Core & Angular project.

Is this expected behavior?

The login performance for the admin user gets worse and worse as the number of records grows in this table.

Also, we noticed the performance degredation after upgrading from 7.3.1 to 8.7.0 in our development environment, which had over 10,000 records for the admin user in AbpUserTokens table.

Hello,

When a role is removed from a user, we need to track who did it (ie. which AbpUser) and when they did it.

The obvious solution is to redefine the UserRole entity so that it inherits from FullAuditedEntity instead of CreationAuditedEntity, but the UserRole entity is defined in a nuget package so we cannot simply change the definition.

Is there a way to achieve this behavior that I am not seeing?

Also, in this post ismcagdas said "You cannot change UserRole to SoftDelete".

Is this also because the UserRole entity is defined in a nuget package, or is there another reason it cannot be done?

Here is what I have tried so far.

Approach 1: I tried handling this at the database level by setting up a delete trigger on the AbpUserRole table which would insert a record into a AbpUserRoleDeleted table, but I can't think of a way to find out which AbpUser made the deletion with this approach. I can only track when the action happened.

Approach 2: I tried listening for the EntityDeleted domain event on UserRole entities, but it does not seem to get triggered. Interestingly, the EntityUpdated event is triggered when I remove a role from a user, but even assuming that this event would only ever be triggered when a UserRole is deleted, the event data still does not include who made the deletion. If it did, I could manually save the audit information in a separate table just like a database delete trigger would, but this time I would have the AbpUser that was responsible for the deletion.

Approach 3: I tried extending the UserRole entity by following the steps here. I was able to implement the IDeletionAudited interface and generate a migration that creates the associated columns on the AbpUserRoles table, but removing a role from a user performs a hard delete instead of a soft delete so I can't tell if the columns even get populated. I am assuming they do not.

Approach 4: I tried enabling Entity History for the UserRole entity, but it seems to only track when a UserRole entity is created.

I will continue exploring more approaches, but in the meantime I would appreciate any help you can provide with this problem.

Thanks!

I added a test modal to the widget-edition-statistics.component to open when the chart is clicked. The modal is not brought to the foreground so its close button cannot be clicked.

Before

After

I want to download v7.3.0 of my existing project from the "Your recent downloads" area at https://aspnetzero.com/Download, but my only options are to download the current version of my project (ie. v7.0.0) or the latest version that is currently available (v8.0.0 at the time I am writing this). Is there a way to download v7.3.0, or even v7.2.0 or v7.1.0 if I so desired?

Showing 1 to 10 of 23 entries