Base solution for your next web application

Activities of "ISTeam"

Answer

To fix this error, I found that ef is not by default included in .NET 3.0 onward releases. So, if we are using .NET Core 3.x then we have to add ef tool packages additionally unlike .NET Core 2.2.

Below were my first two steps in CI pipeline of Azure DevOps but these can be anywhere before the efcore-migration-script-generator task.

steps:

If its .NET Core 3.x

  • task: UseDotNet@2 displayName: 'Use .NET Core sdk 3.x' inputs: packageType: sdk version: 3.x installationPath: $(Agent.ToolsDirectory)/dotnet

For db migration script generator this dependency task is required since .NET Core 3.x

  • task: CmdLine@2 inputs: script: 'dotnet tool install --global dotnet-ef'

...

all other the tasks.

But later I found that this is not a proper way of CI. I created CI using YAML but not using classical editor option as mentioned in the guide. And due to that I am having zip files, XMLs and cmd batch files as well in the artifact which should not be.

But for lot of developers the problem starts from .NET Core 3.x onwards!

Seemed some browser caching issue. I am not able to login in Chrome browser but I can login via Firefox. To test finally I tried cleaning cache and gave a try in 'Edge' browser and surprisingly it worked! Now its working in Firefox also but not in Chrome. So hopefully full system restart may fix any caching issues!

Thanks @maliming for your response. But fortunately by changing the dropdown DOM element name in _CreateModal.cshtml fixed one of the issues : name="EnterpriseClients[]"

Now I can see the dropdown and associate OU with EnterpriseClients as well. Both models are as below :

public class OrganisationUnit : OrganizationUnit
{
    // https://forum.aspnetboilerplate.com/viewtopic.php?f=5&t=11109&hilit=extend
    public virtual bool HasMultipleClients { get; set; }
    public OrganisationUnit()    {    }
    public OrganisationUnit(int? tenantId, string displayName, long? parentId = null) : base(tenantId, displayName, parentId)    {    }
    public IList<OrganisationUnitEnterpriseClient> OrganisationUnitEnterpriseClients { get; set; }
}

// Third entity that contains mapping between OrganizationUnit(OU) and EnterpriseClient(EC)
public class OrganisationUnitEnterpriseClient
{
    public long OrganisationUnitId { get; set; }
    public OrganisationUnit OrganisationUnit { get; set; }
    public int EnterpriseClientId { get; set; }
    public EnterpriseClient EnterpriseClient { get; set; }
}

DashboardDbContext.cs => OnModelCreating method to define many to many relationship for both entities:

modelBuilder.Entity<OrganisationUnitEnterpriseClient>()
    .HasKey(ouec => new { ouec.OrganisationUnitId, ouec.EnterpriseClientId });

With code in original section and above model setup, I am able to save an OU with one or many clients in the database like below:

X.Dashboard.Application\Organizations\OrganizationUnitAppService.cs

public async Task<OrganizationUnitDto> CreateOrganizationUnit(CreateOrganizationUnitInput input)
{
    var organizationUnit = new OrganisationUnit(AbpSession.TenantId, input.DisplayName, input.ParentId);
    await _organizationUnitManager.CreateAsync(organizationUnit);
    
    if (input.EnterpriseClients != null && input.EnterpriseClients.Count > 0)
    {
        if (input.EnterpriseClients.Count > 1)        {            organizationUnit.HasMultipleClients = true;        }
        else        {            organizationUnit.HasMultipleClients = false;        }
        organizationUnit.OrganisationUnitEnterpriseClients = new List<OrganisationUnitEnterpriseClient>();
        // Set mapping between OrganizationUnit and selected EnterpriseClient(s)
        foreach (int enterpriseClientId in input.EnterpriseClients)
        {
            var link = new OrganisationUnitEnterpriseClient()
            {
                EnterpriseClientId = enterpriseClientId,
                OrganisationUnitId = organizationUnit.Id,
                EnterpriseClient = await _enterpriseClientRepository.GetAsync(enterpriseClientId),
                OrganisationUnit = organizationUnit
            };
            organizationUnit.OrganisationUnitEnterpriseClients.Add(link);
        }
    }
    await CurrentUnitOfWork.SaveChangesAsync();
    return ObjectMapper.Map<OrganizationUnitDto>(organizationUnit);
}

Here, my extended class has 's' in the name : OrganisationUnit and the Abp class is OrganizationUnit. For the edit modal I am not sure about the required code change. How to update Dtos and Input models etc. to first show existing relationship between OU and EC - EnterpriseClient and then how to update it? If it was a regular dropdown then using premitive property it could be done hopefully.

But as its a multiselect dropdown plus no example found on the internet or this forum unfortunately that can give some hint on how to achieve that?

Really helpful post while implementing a background service also in .NET Core 3.1 template. UnitOfWork is important to get resolve depencies to access the database!

[UnitOfWork] is the fix for me in .NET Core 3.1 template to implement a default .NET based background service.

Even after two years, surprisingly same thing happened like above comment of @outdoored.

I was spending more than two days to resolve the problem of ObjectDisposedException to access repository in my own separate console applicaiton to be used as a task scheduler job independently just to import data. I first used the exact same code of 'X.Migrator' application and just added my code in the 'MultiTenantMigrateExecuter.Run()' method to access some other reposiotry of the same database. But unfortunately I was getting same error. Even [UnitOfWork] did not work for me.

And as last hope, I restarted my machine and suddenly after restart it is working with [UnitOfWork]! with Tenant repository onlu which is defined by Abp. But not for any other entities created by us.

Even after two years, surprisingly same thing happened like comment by @outdoored on thread 5403 https://support.aspnetzero.com/QA/Questions/5403

I was spending more than two days to resolve the problem of ObjectDisposedException to access repository in my own separate console applicaiton to be used as a task scheduler job independently just to import data.

To make life simple, I first used the exact same code of 'X.Migrator' application and just added my code in the 'MultiTenantMigrateExecuter.Run()' method to access some other reposiotry of the same database. But unfortunately I was getting same error. Even [UnitOfWork] did not work for me.

And as last hope, I restarted my machine and suddenly after restart it is working with [UnitOfWork]! with Tenant repository onlu which is defined by Abp. But not for any other entities created by us.

Fixed it by adding virtual keyword in the method!

@ismcagdas this issue is still present in MVC Core & jQuery template. I followed exact steps to create my first dashboard widget mentioned in the documentation then I got an error :

abpexception there is no permission with name "HelloWorld".

And in fact in the documentation URL there is no mention of how to setup the permission for this particular Widget which they are describing.

So, in addition to adding ".ToList()" change for generalStats, I had to completely remove the HelloWorld permission. Because all the permissions setup are for pages and there is no specific permission for particular Widget. (i.e. tenantWidgetsDefaultPermission is nothing but AppPermissions.Pages_Tenant_Dashboard)

And yes even today, the tenant dashboard is empty because of the AuditLog permission mentioned above!

Thanks @dmux for your explaination and sharing the solution as well!

To use HTTPs URL is a good option. This issue persist even in development machine!

Showing 1 to 10 of 23 entries