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!

We are using version 8.1.0 template of ASP .NET Core MVC & jQuery type. As per this documentation of MVC, I tried to add 'Address' field in my project.

It compiles successfully and I can also see 'Address' field in swagger UI call of "/api/services/app/User/GetUsers" api method response.

But when I load the 'Users' page in the 'Administration' tab with my 'admin' login in dev environment I am getting below error: "DataTables warning: table id=UsersTable - Requested unknown parameter '10' for row 0, column 10. For more information about this error, please see http://datatables.net/tn/4"

On UI one column 'Address' is added but data is not reflecting and as 'Address' is not being bind correctly last column 'Creation Time' is empty. It seems column is added in UI as I have defined column in /Users/index.cshtml but it is not being bound correctly via JS.

I have updated below files with 'Address' column:

  1. .Application.Shared/Authorization/Users/Dto/UserEditDto.cs
  2. .Application/Authorization/Users/Exporting/UserListExcelExporter.cs
  3. .Application/Authorization/Users/UserAppService.cs
  4. .Core.Shared/Authorization/Users/UserConsts.cs
  5. .Core/Authorization/Users/User.cs
  6. .Web.Mvc\Areas\App\Views\Users_CreateOrEditModal.cshtml
  7. .Web.Mvc/Areas/App/Views/Users/Index.cshtml
  8. .Web.Mvc/Areas/App/Views/Users/_CreateOrEditModal.cshtml
  9. .Web.Mvc/wwwroot/view-resources/Areas/App/Views/Users/Index.js
  10. .Web.Mvc/wwwroot/view-resources/Areas/App/Views/Users/Index.min.js
  11. .Web.Mvc\wwwroot\view-resources\Areas\App\Views_Bundles\user-list.min.js

When I create a new user from Create popup, it saves the address correctly in the database and I added dummy address for all existing 5 users and in the DB entity its not set as 'Required' field.

Please advice. Thnx.

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!

I did not find any documentation or tutorial to add a dropdown in 'ASP.NETCore MVC & jQuery' template. I need to add a multi select dropdown in the project to map multiple clients with organization unit inbuilt entity of the template.

I have extended OraganizationUnit entity with many to many relationship with 'EnterpriseClient' entity. In Create OrganizationUnit modal pop-up, there is only one input 'Name'. I have added a multi-select dropdown in that modal to allow user to select one or more EnterpriseClients which I can map from the backend.

The multiselect dropdown is basic and has plain text only. Currently with code similar as below in X.Dashboard.Web.Mvc\Areas\App\Views\OrganizationUnits\ _CreateModal.cshtml:

 <div class="form-group">
        <select class="form-control selectpicker" multiple data-max-options="5" title="Choose Enterprise Client(s)" data-selected-text-format="count"  data-live-search="true" id="EnterpriseClients" name="EnterpriseClients">
            @foreach (var item in @Model.EnterpriseClients)
            {
                <option value="@item.Key" title="@item.Value" data-tokens="@item.Value">@item.Value</option>
            }
        </select>
</div>

Added below code in the init method of X.Dashboard.Web.Mvc\wwwroot\view-resources\Areas\App\Views\OrganizationUnits\ _CreateModal.js

_$OUECCombobox = _modalManager.getModal().find('#EnterpriseClients');
_$OUECCombobox.selectpicker({
    iconBase: "fa",
    tickIcon: "fa fa-check"
});

To setup dropdown text and value, I added below code in X.Dashboard.Web.Mvc\Areas\App\Models\OrganizationUnits\CreateOrganizationUnitModalViewModel.cs

public CreateOrganizationUnitModalViewModel(long? parentId, Dictionary<string, string> enterpriseClients)
{
    ParentId = parentId;
    EnterpriseClients = enterpriseClients;
}
public Dictionary<string, string> EnterpriseClients { get; set; }

Updated code in the controller method to show the dropdown correctly in the create phase : X.Dashboard.Web.Mvc\Areas\App\Controllers\OrganizationUnitsController.cs

[AbpMvcAuthorize(AppPermissions.Pages_Administration_OrganizationUnits_ManageOrganizationTree)]
public PartialViewResult CreateModal(long? parentId)
{
    var enterpriseClients = _enterpriseClientRepository.GetAllList().ToDictionary(ec => ec.Id.ToString(), ec => ec.ClientCode);
    return PartialView("_CreateModal", new CreateOrganizationUnitModalViewModel(parentId , enterpriseClients));
}

Added below property which seems wrong : X.Dashboard.Application.Shared\Organizations\Dto\OrganizationUnitDto.cs public Dictionary<string, string> EnterpriseClientIds { get; set; } X.Dashboard.Application.Shared\Organizations\Dto\CreateOrganizationUnitInput.cs public List<int> EnterpriseClients { get; set; }

I need all the selected EnterpriseClients in the AppService but it was null initially and after making adding two property or some other trial and error to fix the problem I am getting an error in UI when 'Save' button is clicked. X.Dashboard.Application\Organizations\OrganizationUnitAppService.cs

[AbpAuthorize(AppPermissions.Pages_Administration_OrganizationUnits_ManageOrganizationTree)]
public async Task<OrganizationUnitDto> CreateOrganizationUnit(CreateOrganizationUnitInput input)
{
    var organizationUnit = new OrganisationUnit(AbpSession.TenantId, input.DisplayName, input.ParentId);
    if (input.EnterpriseClients != null && input.EnterpriseClients.Count > 0)
    {
        ....
    }
}

No idea how to properly define Dtos for dropdown and how to get those multiple selected values of the dropdown in the backend service call. I also need to make changes in the edit modal, but not sure how and what changes are required.

Below is the error screenshot.

Any suggestions to solve it?

Thanks

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?

I am using ASP.NET Core MVC and jQuery template.

In the master database all Abp tables are there as default. I have added three entities/tables to show in UI.

Using background worker I need to fill the data in those three tables from three different databases of three CRMs, which are neither Abp style nor I have designed the db context. For that I have added three additional connection strings in the appsettings.json file. Downloaded dapper package in X.Dashboard.Core project where my background worker classes to be designed.

Two of the databases are MSSQL and one is MySQL. I have created SQL query on how to select the data from each of them.

How can I connect to those databases from the workers to fire 'SELECT' query using Dapper and then I would insert in my application database.

Should I just go with old way which requires to download nuget package - System.Data.SqlClient like below:

using (SqlConnection db = new SqlConnection(CRM_DbConnectionString))
{
    db.Open();
    Orders = db.Query<Order>(Query_file_content).ToList();
    db.Close();
}

Or is there a better approach in .NET Core 3.1 latest template of ANZ?

Please advise. Thanks.

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.

We have ASP.NET Core MVC and jQuery 8.3 version template. We need to get data from four different CMS systems siting in different DMZs than deployment location of the MVC web applicaiton. So, we cannot use background workers - hosted service to import data directly on deployment server.

For that reason we need to create four console application clients, which will dump data after reading from each CMS system databases. Frequency to import data is also different for all systems, so we can easily configure by creating scheduled job in Windows Task Scheduler. I need to perform only basic CRUD operations on few EFCore entities and reflect in Dashboard database for the import task.

Please advice if there is any sample or documentation on how to create console application to perform such activity using such an independent agent.

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.

Showing 1 to 10 of 32 entries