Activities of "kfrancis@clinicalsupportsystems.com"

I understand that most aren't using WPF, but all of this would be relevant to WinUI/UWP as well - anything that would be deployed as a standalone app.

Answer

Working on something here: https://github.com/kfrancis/abp-wpf

The issue still persists and we're on v5.0.0 RC1 now. The last article made no difference either, all of those things were already in place.

Doh.

Not an issue, just bad code.

Don't attempt to put things in cache that are object.

Answer

ErrorDescription: RequiresTwoFactor

Hi
Can you try to disable the 2FA of your account?

https://account.abp.io/

That does allow the cli to login, but makes our account less secure. It was working with 2FA until recently.

Answer

I have tried:

  • Disabling network security
  • Disabling the network pihole
  • Changing the password (thinking some character was making it fail)
  • Another computer

Looks like the following:

public class BillingGroupRepository : CabMDRepository<BillingGroup, BillingGroup_Id>, IBillingGroupRepository
    {
        #region Constants

        private const string Cmd_BillingGroups_Load = "Billing.BillingGroup_Load_1 ";
        private const string BillingGroupCacheKey = "BillingGroups";

        #endregion Constants

        #region Static Force Version Check Method

        /// <summary>
        /// Force the next load of the entities to do a version check
        /// (In this case, just force a reload)
        /// </summary>
        /// <param name="cache"></param>
        internal static void ForceVersionCheck(IDistributedCache<CacheItem> cache)
        {
            try
            {
                _semaphore.Wait();
                cache.Remove(BillingGroupCacheKey);
            }
            finally
            {
                _semaphore.Release();
            }
        }

        /// <summary>
        /// Force the next load of the entities to do a version check
        /// (In this case, just force a reload)
        /// </summary>
        /// <param name="cache"></param>
        internal async static Task ForceVersionCheckAsync(IDistributedCache<CacheItem> cache)
        {
            try
            {
                await _semaphore.WaitAsync().ConfigureAwait(false);
                await cache.RemoveAsync(BillingGroupCacheKey).ConfigureAwait(false);
            }
            finally
            {
                _semaphore.Release();
            }
        }

        #endregion Static Force Version Check Method

        #region Constructors

        public BillingGroupRepository(IAsyncQueryableExecuter asyncExecuter,
                                      ICurrentUser currentUser,
                                      IConfiguration configuration,
                                      IDistributedCache<CacheItem> cache = null) 
            : base(asyncExecuter, currentUser, configuration, cache)  // these go in the regular distributed cache (see ForceVersionCheck above)
        {
        }

        #endregion Constructors

        public override string EntityTypeName => "Billing Group";
        internal override string CacheKeyPrefix => BillingGroupCacheKey;

        #region Override Caching

        protected override bool IdIsDefault(BillingGroup_Id Id)
        {
            return Id.Value == default;
        }

        protected override void DeleteEntityFromDb(BillingGroup_Id Id)
        {
            throw new NotSupportedException($"Write operations not enabled for {EntityTypeName}s");
        }

        protected override Task DeleteEntityFromDbAsync(BillingGroup_Id Id, CancellationToken ct = default)
        {
            throw new NotSupportedException($"Write operations not enabled for {EntityTypeName}s");
        }

        protected override VersionAndDelete LoadCurrentVersionFromDb()
        {
            return new VersionAndDelete { Version = 0, LastDeletion = DateTime.MinValue };
        }

        protected override DbLoadObj<BillingGroup_Id, BillingGroup> LoadEntitiesFromDb(int fromVersion)
        {
            return Db_LoadBillingGroups(fromVersion);
        }

        protected override Task<VersionAndDelete> LoadCurrentVersionFromDbAsync(CancellationToken ct = default)
        {
            return Task.FromResult(new VersionAndDelete { Version = 0, LastDeletion = DateTime.MinValue });
        }

        protected async override Task<DbLoadObj<BillingGroup_Id, BillingGroup>> LoadEntitiesFromDbAsync(int fromVersion, CancellationToken ct = default)
        {
            return await Db_LoadBillingGroupsAsync(fromVersion, ct).ConfigureAwait(false);
        }

        protected override void SaveEntity(BillingGroup entity)
        {
            throw new NotSupportedException($"Write operations not enabled for {EntityTypeName}s");
        }

        protected override Task SaveEntityAsync(BillingGroup entity, CancellationToken ct = default)
        {
            throw new NotSupportedException($"Write operations not enabled for {EntityTypeName}s");
        }

        protected override DbSaveObj<BillingGroup> SaveEntityToDb(BillingGroup entity, int currentKnownVersion)
        {
            throw new NotSupportedException($"Write operations not enabled for {EntityTypeName}s");
        }

        protected override Task<DbSaveObj<BillingGroup>> SaveEntityToDbAsync(BillingGroup entity, int currentKnownVersion, CancellationToken ct)
        {
            throw new NotSupportedException($"Write operations not enabled for {EntityTypeName}s");
        }

        #endregion Override Caching

        #region DBAccess

        private DbLoadObj<BillingGroup_Id, BillingGroup> Db_LoadBillingGroups(int FromVersion)
        {
            using IDatabase db = new Database(connectionString);
            db.AddParameter(new dbParameter("For15", true));
            DataSet ds = null;
            try
            {
                Database.ExcuteWithRetry(() => ds = db.Execute<DataSet>(Cmd_BillingGroups_Load), RetryLogger);
                return new DbLoadObj<BillingGroup_Id, BillingGroup>
                {
                    List = Db_GetBillingGroupsFromDataSet(ds),
                    Version = 0,
                    AllLoaded = true
                };
            }
            finally
            {
                if (ds != null) ds.Dispose();
            }
        }

        private async Task<DbLoadObj<BillingGroup_Id, BillingGroup>> Db_LoadBillingGroupsAsync(int FromVersion, CancellationToken ct = default)
        {
            ct.ThrowIfCancellationRequested();

            using IDatabase db = new Database(connectionString);
            db.AddParameter(new dbParameter("For15", true));
            DataSet ds = null;
            try
            {
                await Database.ExcuteWithRetryAsync(async () => ds = await db.ExecuteAsync<DataSet>(Cmd_BillingGroups_Load, ct).ConfigureAwait(false), RetryLogger, ct).ConfigureAwait(false);
                return new DbLoadObj<BillingGroup_Id, BillingGroup>
                {
                    List = Db_GetBillingGroupsFromDataSet(ds),
                    Version = 0,
                    AllLoaded = true
                };
            }
            finally
            {
                if (ds != null) ds.Dispose();
            }
        }

        private static ConcurrentDictionary<BillingGroup_Id, BillingGroup> Db_GetBillingGroupsFromDataSet(DataSet ds)
        {
            // the main list
            var retValue = DataTableConcurrentDictionary.CreateDictionary<BillingGroup_Id, BillingGroup>(ds.Tables[0], "ID");
            // get additional values
            var dvDetail = new DataView(ds.Tables[1], null, "BillingGroupID", DataViewRowState.CurrentRows);
            var dvCharge = new DataView(ds.Tables[2], null, "BillingGroupID", DataViewRowState.CurrentRows);
            var dvTax = new DataView(ds.Tables[3], null, "BillingGroupID", DataViewRowState.CurrentRows);
            // loop through each ba to get associated values
            foreach (var bg in retValue.Values)
            {
                // details
                var rows = dvDetail.FindRows(bg.Id).Select(r => r.Row);
                bg.Detail = rows.Any() ? DataTableList.CreateList<BillingGroupDetail>(rows).FirstOrDefault() : null;
                // charges
                rows = dvCharge.FindRows(bg.Id).Select(r => r.Row);
                bg.Charge = rows.Any() ? DataTableList.CreateList<BillingGroupCharge>(rows).FirstOrDefault() : null;
                // taxes
                rows = dvTax.FindRows(bg.Id).Select(r => r.Row);
                bg.Tax = rows.Any() ? DataTableList.CreateList<BillingGroupTax>(rows).FirstOrDefault() : null;
            }
            return retValue;
        }

        #endregion DBAccess
    }

The base CabMDRepository takes IConfiguration so that it can do this:

connectionString = configuration.GetConnectionString("Default");

And so in the set of tests that I want to run that check these ado/sp loading methods, I want to specify the connection string so that we can actually test.

Here's the related code:

Domain

[DependsOn(
        typeof(CabMDDomainSharedModule),
        typeof(AbpAuditLoggingDomainModule),
        typeof(AbpBackgroundJobsDomainModule),
        typeof(AbpFeatureManagementDomainModule),
        typeof(AbpIdentityProDomainModule),
        typeof(AbpPermissionManagementDomainIdentityModule),
        typeof(AbpIdentityServerDomainModule),
        typeof(AbpPermissionManagementDomainIdentityServerModule),
        typeof(AbpSettingManagementDomainModule),
        typeof(SaasDomainModule),
        typeof(TextTemplateManagementDomainModule),
        typeof(LeptonThemeManagementDomainModule),
        typeof(LanguageManagementDomainModule),
        typeof(VoloAbpCommercialSuiteTemplatesModule),
        typeof(AbpEmailingModule),
        typeof(BlobStoringDatabaseDomainModule),
        typeof(AbpPaymentDomainModule),
        typeof(AbpPaymentPayuDomainModule),
        typeof(AbpPaymentTwoCheckoutDomainModule),
        typeof(FileManagementDomainModule), 
        typeof(DocsDomainModule),
        typeof(CmsKitProDomainModule)
        )]
    public class CabMDDomainModule : AbpModule
    {
        // lots of code
    }

EfCore (Unified)

[DependsOn(
        typeof(CabMDDomainModule),
        typeof(AbpIdentityProEntityFrameworkCoreModule),
        typeof(AbpIdentityServerEntityFrameworkCoreModule),
        typeof(AbpPermissionManagementEntityFrameworkCoreModule),
        typeof(AbpSettingManagementEntityFrameworkCoreModule),
        typeof(AbpEntityFrameworkCoreSqlServerModule),
        typeof(AbpBackgroundJobsEntityFrameworkCoreModule),
        typeof(AbpAuditLoggingEntityFrameworkCoreModule),
        typeof(AbpFeatureManagementEntityFrameworkCoreModule),
        typeof(LanguageManagementEntityFrameworkCoreModule),
        typeof(SaasEntityFrameworkCoreModule),
        typeof(TextTemplateManagementEntityFrameworkCoreModule),
        typeof(BlobStoringDatabaseEntityFrameworkCoreModule),
        typeof(AbpPaymentEntityFrameworkCoreModule),
        typeof(FileManagementEntityFrameworkCoreModule),
        typeof(DocsEntityFrameworkCoreModule),
        typeof(CmsKitProEntityFrameworkCoreModule)
        )]
    public class CabMDEntityFrameworkCoreModule : AbpModule
    {
        // lots of code
    }

Unified DbContext:

protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            /* Include modules to your migration db context */

            builder.ConfigurePermissionManagement();
            builder.ConfigureSettingManagement();
            builder.ConfigureBackgroundJobs();
            builder.ConfigureAuditLogging();
            builder.ConfigureIdentityPro();
            builder.ConfigureIdentityServer();
            builder.ConfigureFeatureManagement();
            builder.ConfigureLanguageManagement();
            builder.ConfigureSaas();
            builder.ConfigureTextTemplateManagement();
            builder.ConfigureCmsKitPro();
            builder.ConfigureBlobStoring();
            builder.ConfigurePayment();
            builder.ConfigureFileManagement();
            builder.ConfigureDocs();

            /* Configure the shared tables (with included modules) here */

            //builder.Entity<IdentityUser>(b =>
            //{
            //    b.ToTable(AbpIdentityDbProperties.DbTablePrefix + "Users"); //Sharing the same table "AbpUsers" with the IdentityUser

            //    b.ConfigureByConvention();
            //    b.ConfigureAbpUser();

            //    /* Configure mappings for your additional properties.
            //     * Also see the CabMDEfCoreEntityExtensionMappings class.
            //     */
            //});

            /* Configure your own tables/entities inside the ConfigureCabMD method */

            builder.ConfigureCabMD();
        }

I'll note also that the abp suite refuses to bring up modules and the abp add-module command says it's failing but provides no information. Is there a way to get more verbose information from the CLI there?

All of those things are in place, and I've done them again with no success. Also, when I go to add a migration - it's empty and I can see that it's because the blob related tables are in from when I added CmsKitPro.

Can I email you? Since I can't produce this on a new project.

So, I've been trying to re-create the issue but I haven't yet found a set of steps useful.

I'm wondering if it's due to us adding the CmsPro kit module before this. Is there an order that is important?

Showing 21 to 30 of 36 entries
Made with ❤️ on ABP v9.0.0-preview Updated on September 19, 2024, 10:13