Base solution for your next web application

Activities of "BigCDogCrew"

AspNetZero v8.4, Abp 5.5, Mvc/jQuery

Inside [account-layout-libs.min.js] and also [account-layout-libs.min.js]

        defaultError404: {
          message: 'Resource not found!',
          details: 'The resource requested could not found on the server.'
        },

The details value should be changed to 'The resource requested could not be found on the server.'

AspNetZero v8.4, Abp 5.5, Mvc/jQuery. (EFCore3)

We are planning to upgrade our project to the latest version of AspNetZero (and EFCore6). We are currently using Mvc/jQuery but want to move in the direction of Angular.

We would like to maintain the legacy Mvc/jQuery pages as we author new pages of the system in Angular. We will update the legacy pages to Angular as time permits...but may take several years.

Is this migration path possible? What challenges will we face?

Login As Tenant -VS- Login As User

AspNetZero v8.4, Abp 5.5, Mvc/jQuery

Description of Issue An issue came up where a user had been granted permission to login as a tenant but was NOT granted permission to login as a user. The UI correctly presented the user with the opportunity to login as one of the tenant's users, but then failed immedaitely when they selected a target user account from the list.

Assessment It seems like tenant impersonation is useless without user impersonation. So, how is tenant impersonation really supposed to work? I can think of two ways.

Option #1 - treat tenant impersonation as a broader form of user impersonation. Whereever user impersonation rights are allowed, also allow tenant impersonation. The net effect is that granting tenant impersonation automatically grants user impersonation (regardless of the specific state of user impersonation permission).

Option #2 - treat tenant impersonation as a specific form of user impersonation. When exercising the tenant impersonation right in the absence of the user impersonation right, DO NOT display a list of user accounts, but immediately login as the admin user account of the specified tenant. However, if the user impersonation right is ALSO granted, then display the user list for selection of a specific account to impersonate.

Question What am I missing? Why does the system function the way it does today, where both permissions have to be enabled in order to effectively grant tenant impersonation?

AspNetZero v8.4, Abp 5.5, Mvc/jQuery.

I noticed that any reference I make to a foreign key property causes the SQL query to use a SELECT * on the foreign key table...not just SELECT field.

This code...

	var parentId = 1;	
	var orgUnits =  _organizationUnitRepository
		.GetAll()
		.Where(e => e.Parent.Id == parentId)
		.ToList();

Generates this SQL.... NOTE A: tenancy filters have been replaced for abbreviation. NOTE B: the first select * is expected, but the LEFT JOIN selection should have been only [a0].[Id]

SELECT [a].[Id], [a].[Code], [a].[CreationTime], [a].[CreatorUserId], [a].[DeleterUserId], [a].[DeletionTime], [a].[DisplayName], [a].[IsDeleted], [a].[LastModificationTime], [a].[LastModifierUserId], [a].[ParentId], [a].[TenantId]
FROM [AbpOrganizationUnits] AS [a]
LEFT JOIN (
    SELECT [a0].[Id], [a0].[Code], [a0].[CreationTime], [a0].[CreatorUserId], [a0].[DeleterUserId], [a0].[DeletionTime], [a0].[DisplayName], [a0].[IsDeleted], [a0].[LastModificationTime], [a0].[LastModifierUserId], [a0].[ParentId], [a0].[TenantId]
    FROM [AbpOrganizationUnits] AS [a0]
    WHERE (tenancyFilter2)
) AS [t1] ON [a].[ParentId] = [t1].[Id]
WHERE (tenancyFilter1) AND ([t1].[Id] = @__p_0)

Using LinqPad with EF 3.1.15

This code...

    AbpOrganizationUnits.Where(e => e.Parent.Id == 1).Select(x => x.Code)

Generates this SQL...

SELECT [t0].[Code]
FROM [AbpOrganizationUnits] AS [t0]
LEFT OUTER JOIN [AbpOrganizationUnits] AS [t1] ON [t1].[Id] = [t0].[ParentId]
WHERE [t1].[Id] = @p0

So, where and why is AbpNetZero or Abp expanding the join selection to include all fields rather than using only the necessary fields?

I don't have any metrics on how this is affecting our performance. But, I assume it is substantial because it affects 99% of our queries.

BTW, I also tried this with a direct dbContext call with the same result.

  var parentId = 1;	
  var contextUnits = _dbContext.GetDbContext().OrganizationUnits
                .Where(e => e.Parent.Id == parentId)
                .ToList();

AspNetZero v8.4, Abp 5.5, Mvc/jQuery.


ORIGINAL MESSAGE SENT BY EMAIL


We have a query that suffers from parameter sniffing, where execution of the EF-generated query takes 10 seconds to return 1 row, but if you can convert it to T-SQL, it executes immediately. If I were to solve this problem using a Microsoft-centric mindset, I would add code similar to this link: Interceptors - EF Core | Microsoft Docs

var blogs1 = context.Blogs.TagWith("Use hint: recompile plan").ToList();

That EF statement would then generate SQL that looked like this: -- Use hint: robust plan

SELECT [b].[Id], [b].[Name] FROM [Blogs] AS [b] OPTION (RECOMPILE)

In the EF6 days, I used this same technique with success, and it looked like this: How to add OPTION RECOMPILE into Entity Framework - Stack Overflow

Is there a sample that you can point to where the ASP.NET Zero classes can enable per-context/per-statement query hint generation?

Thanks for any help.

<br>


ORIGINAL RESPONSE RECEIVED BY EMAIL


I think you are trying to detect the cause of the problem. If so, you can inject IDbContextProvider and get the DbContext using this class and execute a method like you have shared in your email for including recompile plan.

If this is not for detecting the problem, then you can create a custom repository (https://aspnetboilerplate.com/Pages/Documents/Repositories#custom-repositories)  and place the same query in it.

<br> <br>


UPDATED QUESTION


Is there a ready-made sample available somewhere that would show how to implement the EF Core Interceptor (TaggedQueryCommandInterceptor [ref: https://docs.microsoft.com/en-us/ef/core/logging-events-diagnostics/interceptors]) in an ABP repository? We have code that looks like this in an AppService:

private readonly IRepository&lt;OrganizationUnit, long> _organizationUnitRepository;

public async Task&lt;GetUserForEditOutput> GetUserForEdit(NullableIdDto&lt;long> input) { var allOrganizationUnits1 = await _organizationUnitRepository.GetAllListAsync(); … }

I would love to be able to specify the query hint on an individual query, based on our investigation into whether a specific query will need it or not. So the last statement would maybe look something like: var allOrganizationUnits1 = await _organizationUnitRepository.OptionRecompile().GetAllListAsync();

and the resulting query would use the EF interceptor to add the OPTION RECOMPILE SQL query hint.

Thanks again.

AspNetZero v8.4, Abp 5.5, Mvc/jQuery.

Under the profile icon, if you click on "Manage linked accounts", close the dialog, and then immediately click on the "Manage linked accounts" again, the system throws a datatables reinitialization error.

Because this is a timing issue, you may have to perform the process a few times. However, it is a very repeatable.bug.

Although the "Manage authority delegations" option functions very similarly, this menu option does NOT exhibit the same behavior...and may be a key to helping figure out what is different between the two.

AspNetZero v8.6 MVC/jQuery .Net Core Abp.TestBase v5.5

When I connect my unit tests to a SQLServer database, I am able to call application services with appropriate permissions. When I switch to using the in-memory SQLLite database, the [MyProject]AuthorizationHelper.PermissionChecker.AuthorizeAsync throws an exception.

As far as I can tell, there is either (A) an issue with the data being different betweeen the two databases or (B) an issue with the Abp code/handlers associated with SQLLite.

I have meticulously recreated the SQLServer database in the [MyProject].Test.Base.TestData.TestDataBuilder population of the SQLLite instance. So, I'm now leaning toward option B.

	public class TestDataBuilder : ITestDataBuilder
	{
		protected readonly PGSAspectDbContext _context;
		protected readonly int _tenantId;
		protected readonly RoleManager roleManager;
		protected readonly UserManager userManager;
		protected readonly TenantManager tenantManager;
		protected readonly ISessionTenantFilterList sessionTenantFilterList;

		public TestDataBuilder(PGSAspectDbContext context, int tenantId, TenantManager tenantManager, UserManager userManager, RoleManager roleManager, ISessionTenantFilterList sessionTenantFilterList)
		{
			_context = context;
			_tenantId = tenantId;
			this.roleManager = roleManager;
			this.userManager = userManager;
			this.tenantManager = tenantManager;
			this.sessionTenantFilterList = sessionTenantFilterList;
		}

		public virtual void Create()
		{
			_context.SaveChanges();

			new TestData_AbpEditions(_context).Create();
			new TestData_AbpUsersHost(userManager, roleManager).Create(); _context.SaveChanges(); 
			new TestData_AbpTenants(tenantManager, roleManager).Create(); _context.SaveChanges(); // Prerequisites: Edition
			new TestData_AbpSettings(_context).Create();                                          // Prerequisites: Tenant
			new TestData_AbpFeatures(_context).Create();                                          // Prerequisites: Edition, Tenant
			new TestData_AbpRoles(_context).Create();                                             // Prerequisites: Tenant
			new TestData_AbpUsers(userManager, roleManager).Create();    _context.SaveChanges();  // Prerequisites: Tenant, Roles
			new TestData_AbpUserAccounts(_context).Create();                                      // Prerequisites: Tenant, Users
			new TestData_AbpPermissions(_context).Create();                                       // Prerequisites: Tenant, Roles, Users
			
			new TestData_Clients(_context).Create();
			new TestData_AbpOrganizationUnits(_context, sessionTenantFilterList).Create();

			_context.SaveChanges();
		}
	}

NOTE: We are using MultiTenancy and we are highly integrated into the OrganizationalUnits. The ISessionTenantFilterList is our set of custom filters that allow us to expose data up and down the OrganizationalUnit hierarchy based upon Edition, Organziational Level, and TEntity. (I am certain this issue is unrelated to our custom filters, though I have not yet ruled out the possibility that it is related to MultiTenancy.)

Here is the test that triggers the error....

		[MultiTenantFact]
		public async Task Test_Create()
		{
			//Arrange
			LoginAsTenant("xxx", "admin");
			var mockInput = new FakeCreateOrEditStoreDto();

			//Act
			await _storesAppService.CreateOrEdit(mockInput);

			//Assert
			UsingDbContext(context =>
			{
				var store = context.Stores.FirstOrDefault(e => e.UID == mockInput.UID);
				store.ShouldNotBeNull();
				store.Name.ShouldBe(mockInput.Name);
			});
		}

The error reiceved looks like this...

I noticed that trapping the breakpoint BEFORE execution of PermissionChecker, there are no ActiveDbContexts (see below).

AFTER execution/exception, an ActiveDbContext reference has been set, but there are no permissions available (see below).

If I click on the Results View, the context is refreshed and the permissions become available (see below).

When I change to using LoginAsHost("admin"), I get a different but seemingly related error (see below).

I am probably doing something stupid, but any insights that you can offer are greatly appreciated.

AspNetZero 7.2 MVC / jQuery.

I seriously hope I'm not doing something stupid-easy and wasting your time with this one, but I just don't see it.

When attempting to import users from an excel spreadsheet, the individual user records are rejected with a "Nullable object must have a value" error. Then, the try-catch builds the list of these invalid users and when attempting to publish the notification fails again with the same error.

Here are the records in the import file. <br> | UserName* | Name* | Last Name* | EmailAddress* | PhoneNumber | Password* | AssignedRoleNames (comma separated) | | --------- | ----- | ---------- | ------------- | ----------- | --------- | ----------------------------------- | | Mickey | Mickey | Mouse | [email protected] | 2342342345 | 123qwe | User | | Minnie | Minnie | Mouse | [email protected] | 2342342346 | 123qwe | Admin | | Donald | Donald | Duck | [email protected] | 2342342347 | 123qwe | User | | Daisy | Daisy | Duck | [email protected] | 2342342348 | 123qwe | Admin | | Scrooge | Scrooge | McDuck | [email protected] | 2342342349 | 123qwe | Admin | <br> Here are the two images of the locations where the errors are occurring.

AspNetZero v7.2, MVC, jQuery

Often (but not always), the username is not recorded in the AuditLog during login. It seems to work reliably during logout. Also, it does not appear to record the tenant in either case. I have looked, but can not see in the code where the AuditLog is being written. I have also tried to force a few SaveChanges() on the current UnitOfWorkManager in various places to see if I could figure out if the log is being written by ABP dlls; but I was unsuccessful. Where is this happening? How can I add more information to the AuditLog record before it is written?

AspNetZero 7.2.0 MVC Core jQuery. Where is the best place to put code that will execute just once during user login?

Showing 1 to 10 of 18 entries