Activities of "Sturla"

I´m trying to figure out how to use the CancellationTokenProvider insted of adding CancellationToken to all my ApplicationService methods and then passing CancellationToken to them in my UI.

I might be misunderstanding how this is supposed to work but the documentation on this is serverly lacking

When navigating from the page should cancel the reqest and make IsCancellationRequested == true or do I have to do something in the UI?

Here is my code where I added a Task.Delay to the repository method to be able to then quickly navigate from that page.

Could this be related to Blazor Server? IF it doesn´t work with BS then it would be great to add that to the documentation.

UPDATE: I was also unsuccesfull passing token manually into the methods (something I was hoping I didn´t need to do)

Blazor

@inject INavigationInterception NavigationInterception

private CancellationTokenSource _cts = new();

protected override async Task OnInitializedAsync()
{
    await NavigationInterception.EnableNavigationInterceptionAsync();
    NavigationManager.LocationChanged += HandleLocationChanged;
}

private async Task OpenEditBookModalAsync(BookDto input)
{
    var book = await BooksAppService.GetAsync(input.Id, _cts.Token); // Pass CancellationToken

    EditingBookId = book.Id;
    EditingBook = ObjectMapper.Map<BookDto, BookUpdateDto>(book);
    await EditingBookValidations.ClearAll();
    await EditBookModal.Show();
}

private void HandleLocationChanged(object sender, LocationChangedEventArgs e)
{
    _cts.Cancel(); // Cancel the current operations
}

public async ValueTask DisposeAsync()
{
    NavigationManager.LocationChanged -= HandleLocationChanged;
    _cts?.Cancel();
    _cts?.Dispose();
}
public virtual async Task<PagedResultDto<BookDto>> GetListAsync(GetBooksInput input, CancellationToken cancellationToken)
{
    var totalCount = await _bookRepository.GetCountAsync(input.FilterText, input.Name, input.Email, cancellationToken);
    var items = await _bookRepository.GetListAsync(input.FilterText,
     input.Name,
      input.Email,
       input.Sorting,
        input.MaxResultCount,
         input.SkipCount,
          cancellationToken);
    return new PagedResultDto<BookDto>
    {
        TotalCount = totalCount,
        Items = ObjectMapper.Map<List<Book>, List<BookDto>>(items)
    };
}

Repository

    public abstract class EfCoreBookRepositoryBase : EfCoreRepository<CasaDbContext, Book, Guid>
    {
        public EfCoreBookRepositoryBase(IDbContextProvider<CasaDbContext> dbContextProvider)
            : base(dbContextProvider)
        {

        }

        public virtual async Task<List<Book>> GetListAsync(
            string? filterText = null,
            string? name = null,
            string? email = null,
            string? sorting = null,
            int maxResultCount = int.MaxValue,
            int skipCount = 0,
            CancellationToken cancellationToken = default)
        {
            Task.Delay(10000).Wait();
            var query = ApplyFilter((await GetQueryableAsync()), filterText, name, email);
            query = query.OrderBy(string.IsNullOrWhiteSpace(sorting) ? BookConsts.GetDefaultSorting(false) : sorting);
            return await query.PageBy(skipCount, maxResultCount).ToListAsync(cancellationToken);
        }
       }

How should this work? 🤷‍♂️🤨

  • ABP Framework version: 8.0.5
  • UI Type: Blazor Server
  • Database System: EF Core

Is it possible to have one running application that has

  • both the admin and public functionality in one place (not backend/frontend application)?

Something like:

  • Tenants would control the CMS (when logged in) (www.tenant.domain.com)
    • Not logged in users would see the result (blog/pages/menus/etc)
  • Host admin have CMS for the host domain ((www.domain.com)
    • plush would be that the host could create menu items that would apply for all tenants

Tenant could create a Blog page like this

and view it like this on the same application, not having to have another application instance (public web)?

It is cheaper and easier to have it all in one solution.

p.s I tried this in Blazor Server.. is that maybe not supported? And if so are there any other restrictions or limitations for Blazor?

e.s I tried this also with MVC and had some different strangeness https://support.abp.io/QA/Questions/6711/Bugs--Issues-v81x#answer-3a115a09-806f-bf69-6f41-319509df51ef

Abp.io Blazor Server 8.0.5

I´m going to create a multi tenant application and utilize the abp.io CMS part as much as possible.

My future tenants uses will want to have custom look and feel on their customer facing sites (each site will have custom DNS url) but I want to offer them few different starting options. The admin look and feel for a tenant can use LeptonX Theme no problem)

  1. How can I give them options of choosing between different starting UI´s.
  2. Can I pre-save the look and feel (menus, CSS etc) into CMS and somehow let the user choose from them before starting?

These here below are just some examples that could come from sites like https://wrapbootstrap.com/

https://wrapbootstrap.com/theme/exterior-architecture-interior-template-WB0639D28 (site https://exterior.websitelayout.net/)

another example https://wrapbootstrap.com/theme/shopapp-ecommerce-bootstrap-5-template-WB0X496C5 (site https://www.pxdraft.com/wrap/shopapp/html/home/index.html)

I´m updating my system (dev) to abp.io 8.0.2 where altering the AbpAuditLogs table causes the error here below.

It only had 155.174 rows.

The migration works if I delete everything from the table.

Question: How can I run this migration without timeout? I don´t want to delete all my auditlogs on production where I have 422.016 rows.

2024-03-10T16:27:33.2500677Z [16:27:33 INF] Migrating schema for host database...
2024-03-10T16:29:04.9441951Z [16:29:04 ERR] Failed executing DbCommand (30,021ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
2024-03-10T16:29:04.9442707Z DECLARE @var96 sysname;
2024-03-10T16:29:04.9443161Z SELECT @var96 = [d].[name]
2024-03-10T16:29:04.9443548Z FROM [sys].[default_constraints] [d]
2024-03-10T16:29:04.9444163Z INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id]
2024-03-10T16:29:04.9444655Z WHERE ([d].[parent_object_id] = OBJECT_ID(N'[AbpAuditLogs]') AND [c].[name] = N'ExtraProperties');
2024-03-10T16:29:04.9445171Z IF @var96 IS NOT NULL EXEC(N'ALTER TABLE [AbpAuditLogs] DROP CONSTRAINT [' + @var96 + '];');
2024-03-10T16:29:04.9445624Z UPDATE [AbpAuditLogs] SET [ExtraProperties] = N'' WHERE [ExtraProperties] IS NULL;
2024-03-10T16:29:04.9446098Z ALTER TABLE [AbpAuditLogs] ALTER COLUMN [ExtraProperties] nvarchar(max) NOT NULL;
2024-03-10T16:29:04.9446562Z ALTER TABLE [AbpAuditLogs] ADD DEFAULT N'' FOR [ExtraProperties];
2024-03-10T16:29:05.6208988Z Unhandled exception. Microsoft.Data.SqlClient.SqlException (0x80131904): Execution Timeout Expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.
2024-03-10T16:29:05.6209680Z  ---> System.ComponentModel.Win32Exception (258): The wait operation timed out.
2024-03-10T16:29:05.6210441Z    at Microsoft.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
2024-03-10T16:29:05.6211142Z    at Microsoft.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
2024-03-10T16:29:05.6213443Z    at Microsoft.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
2024-03-10T16:29:05.6213994Z    at Microsoft.Data.SqlClient.SqlCommand.InternalEndExecuteNonQuery(IAsyncResult asyncResult, Boolean isInternal, String endMethod)
2024-03-10T16:29:05.6214477Z    at Microsoft.Data.SqlClient.SqlCommand.EndExecuteNonQueryInternal(IAsyncResult asyncResult)
2024-03-10T16:29:05.6214897Z    at Microsoft.Data.SqlClient.SqlCommand.EndExecuteNonQueryAsync(IAsyncResult asyncResult)
2024-03-10T16:29:05.6215422Z    at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
2024-03-10T16:29:05.6215857Z --- End of stack trace from previous location ---
2024-03-10T16:29:05.6216332Z    at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQueryAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
2024-03-10T16:29:05.6216910Z    at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQueryAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
2024-03-10T16:29:05.6217508Z    at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteNonQueryAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
2024-03-10T16:29:05.6218117Z    at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQueryAsync(IEnumerable`1 migrationCommands, IRelationalConnection connection, CancellationToken cancellationToken)
2024-03-10T16:29:05.6219411Z    at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQueryAsync(IEnumerable`1 migrationCommands, IRelationalConnection connection, CancellationToken cancellationToken)
2024-03-10T16:29:05.6228716Z    at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQueryAsync(IEnumerable`1 migrationCommands, IRelationalConnection connection, CancellationToken cancellationToken)
2024-03-10T16:29:05.6274637Z    at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationCommandExecutor.ExecuteNonQueryAsync(IEnumerable`1 migrationCommands, IRelationalConnection connection, CancellationToken cancellationToken)
2024-03-10T16:29:05.6276499Z    at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.MigrateAsync(String targetMigration, CancellationToken cancellationToken)
2024-03-10T16:29:05.6318174Z    at BSR.Beinni.EntityFrameworkCore.EntityFrameworkCoreBeinniDbSchemaMigrator.MigrateAsync() in D:\a\1\s\src\BSR.Beinni.EntityFrameworkCore\EntityFrameworkCore\EntityFrameworkCoreBeinniDbSchemaMigrator.cs:line 28
2024-03-10T16:29:05.6318733Z    at BSR.Beinni.Data.BeinniDbMigrationService.MigrateDatabaseSchemaAsync(Tenant tenant) in D:\a\1\s\src\BSR.Beinni.Domain\Data\BeinniDbMigrationService.cs:line 96
2024-03-10T16:29:05.6322334Z    at BSR.Beinni.Data.BeinniDbMigrationService.MigrateAsync() in D:\a\1\s\src\BSR.Beinni.Domain\Data\BeinniDbMigrationService.cs:line 53
2024-03-10T16:29:05.6325296Z    at BSR.Beinni.DbMigrator.DbMigratorHostedService.StartAsync(CancellationToken cancellationToken) in D:\a\1\s\src\BSR.Beinni.DbMigrator\DbMigratorHostedService.cs:line 39
2024-03-10T16:29:05.6325981Z    at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>b__15_1(IHostedService service, CancellationToken token)
2024-03-10T16:29:05.6326556Z    at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable`1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List`1 exceptions, Func`3 operation)
2024-03-10T16:29:05.6327040Z    at Microsoft.Extensions.Hosting.Internal.Host.&lt;StartAsync&gt;g__LogAndRethrow|15_3(&lt;&gt;c__DisplayClass15_0&)
2024-03-10T16:29:05.6327419Z    at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
2024-03-10T16:29:05.6328422Z    at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
2024-03-10T16:29:05.6329008Z    at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
2024-03-10T16:29:05.6329425Z    at BSR.Beinni.DbMigrator.Program.Main(String[] args) in D:\a\1\s\src\BSR.Beinni.DbMigrator\Program.cs:line 31
2024-03-10T16:29:05.6329797Z    at BSR.Beinni.DbMigrator.Program.&lt;Main&gt;(String[] args)
2024-03-10T16:29:05.6330103Z ClientConnectionId:ce9179cc-e820-4477-81be-a41837b33ad2
2024-03-10T16:29:05.6330426Z Error Number:-2,State:0,Class:11

this is my migration

    name: "ExtraProperties",
    table: "AbpAuditLogs",
    type: "nvarchar(max)",
    nullable: false,
    defaultValue: "",
    oldClrType: typeof(string),
    oldType: "nvarchar(max)",
    oldNullable: true);

migrationBuilder.AlterColumn&lt;string&gt;(
    name: "ConcurrencyStamp",
    table: "AbpAuditLogs",
    type: "nvarchar(40)",
    maxLength: 40,
    nullable: false,
    defaultValue: "",
    oldClrType: typeof(string),
    oldType: "nvarchar(40)",
    oldMaxLength: 40,
    oldNullable: true);

I´m guessing this is connected to the size of the database server or need to incresing the size of the database to handle the migration. I´m guessing the production server can handle the migration but is there any standard way to do this (other than beefing up the hardware)?

  • ABP Framework version: v8.0.2
  • UI Type: Blazor Server
  • Database System: EF Core (SQL Server
  • Tiered (for MVC) or Auth Server Separated (for Angular): no

Is there a good reason why its not possible to setup one-to-many relationship with Suite?

The current "one-to-many" only creates one-to-one relationship!

This here below gets created when I use the "add one-to-many navigational property" (1-n) from the Suite UI (example is where ScrapingConfiguration that should have many different ScrapingUrlId).

public class ScrapingConfiguration : FullAuditedAggregateRoot<Guid>
{
    [NotNull]
    public virtual string Name { get; set; }
    
    // Navigation property created by Suite that is one-to-ONE and not one-to-many relationship
    public virtual Guid? ScrapingUrlId{ get; set; }
}

But take a look at this question for details (why is it even called one-to-many in the UI?)

@alper answers with

ABP Suite helps to create basic CRUD pages with limited relationship options. if you need further steps, you should manually edit the generated code.

But I know that I can manually do this either by adding code like this

// Navigation property to represent the one-to-many relationship that needs to be manually added
// and one that Suite will remove when Save and create is pressed!
public virtual ICollection< ScrapingUrlId > ScrapingUrlIds{ get; set; }

or by updating the DbContext builder code like suggested here

BUT if I use Suite again it will remove that code every time I update it!

This just must be something that you can add?

p.s

There are lots of questions about this issue but nothing in the docs... I would suggest adding a One-to-many (like you have Many-to-many) part under the Generating a CRUD page

After updating (from 7.2.2) I´m getting the error below when running my tests. I´m getting this for all my tests. After having searched I found this 2 year old issue and that led me to unchecking the required tick for the navigation property and the tests started working!

Volo.Abp.AbpInitializationException : An error occurred during the initialize Volo.Abp.Modularity.OnApplicationInitializationModuleLifecycleContributor phase of the module LF.SearchPortal.SearchPortalTestBaseModule, LF.SearchPortal.TestBase, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null: An error occurred while saving the entity changes. See the inner exception for details.. See the inner exception for details. ---- Microsoft.EntityFrameworkCore.DbUpdateException : An error occurred while saving the entity changes. See the inner exception for details. -------- Microsoft.Data.Sqlite.SqliteException : SQLite Error 19: 'FOREIGN KEY constraint failed'.

    Stack Trace: 
ModuleManager.InitializeModules(ApplicationInitializationContext context)
AbpApplicationBase.InitializeModules()
AbpApplicationWithExternalServiceProvider.Initialize(IServiceProvider serviceProvider)
AbpIntegratedTest`1.ctor()
SearchPortalTestBase`1.ctor()
SearchPortalDomainTestBase.ctor()
SampleDomainTests.ctor() line 18
RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean wrapExceptions)
----- Inner Stack Trace -----
ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
<30 more frames...>
ModuleManager.InitializeModules(ApplicationInitializationContext context)
----- Inner Stack Trace -----
SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
SqliteDataReader.NextResult()
SqliteCommand.ExecuteReader(CommandBehavior behavior)
SqliteCommand.ExecuteReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
SqliteCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)

Btw I expect to get this question refunded since this feature is not working and has caused me half a day of nothing...

  • ABP Framework version: v7.3.2
  • UI Type: Blazor Server
  • Database System: EF Core PostgreSQL
  • Tiered (for MVC) or Auth Server Separated (for Angular): no

The details of my issue are listed up in this StackOverflow question (please don´t make me repeat it here)

But basically get this error

Npgsql.PostgresException (0x80004005): 28P01: password authentication failed for user "***"

But if I create a clean EF core project (no abp.io) I´m able to connect to the server and apply migrations using my user/pass that doesn´t work with the abp.io migrator. This here is the code that is working from within a docker

So what do I need to do or add to make this work?

  • ABP Framework version: v7.2.2
  • UI Type: Blazor Server
  • Database System: EF Core (PostgreSQL

I have these two tables, Conversations and ConversationMessages with one-to-many relationship (Conversations table holds onto 1 conversation topic and ConversationMessages is the recording of many back and fourth communication)

If I only have these timestamp columns in my Conversation table I need to create some dummy column to be used for a display property. Now I created this NeededToGenerate column that I´m never going to use and I hate it.

Is this a shortcoming of Suite or should I do this in some other manner?

  • ABP Framework version: v7.2.2
  • UI type: Blazor
  • DB provider: EF Core / Postgress
  • Tiered (MVC) or Identity Server Separated (Angular): no

I´m just reporting an issue that I have (see step 3) worked around and expect to get refunded.

Issue The Docker-compose.yml file is not created correctly and doesn´t work out of the box for a solution created with Suite like this

If you create a new solution with suite as above image you will

1 get this error in the docker-compose.yml file.

Incorrect type. Expected "array | docker-compose.yml" in docker-compose.yml

The depends_on: is missing - postgres

2 I picked Postgres but the docker-compose.yml contains sql-server but should be "postgres"

3 This is what I ended up creating. I´m no docker expert and got the help from my GPT friend. It would be great if this would just work out of the box!

version: '3.8'

services:
  searchportal-blazor:
    image: lf/searchportal-blazor:latest
    container_name: searchportal-blazor
    build:
      context: ../../
      dockerfile: src/LF.SearchPortal.Blazor/Dockerfile.local
    environment:
      - ASPNETCORE_URLS=https://+:443;http://+:80;
      - Kestrel__Certificates__Default__Path=/root/certificate/localhost.pfx
      - Kestrel__Certificates__Default__Password=91f91912-5ab0-49df-8166-23377efaf3cc
      - App__SelfUrl=https://localhost:44314
      - AuthServer__RequireHttpsMetadata=false      
      - AuthServer__Authority=http://searchportal-blazor
      - ConnectionStrings__Default=Host=postgres;Database=SearchPortal;Username=postgres;Password=myPassw0rd;
    ports:
      - "44314:443"
    restart: on-failure
    volumes:
      - ./certs:/root/certificate
    networks:
      - abp-network
    depends_on:
      - postgres

  db-migrator:
    image: lf/searchportal-db-migrator:latest
    container_name: db-migrator
    build:
      context: ../../
      dockerfile: src/SearchPortal.DbMigrator/Dockerfile.local
    environment:
      - OpenIddict__Applications__SearchPortal_BlazorServerTiered__RootUrl=https://localhost:44314
      - ConnectionStrings__Default=Host=postgres;Database=SearchPortal;Username=postgres;Password=myPassw0rd;
    depends_on:
      postgres:
        condition: service_healthy
    networks:
      - abp-network
  
  postgres:
    image: postgres:latest
    container_name: postgres
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: "postgres"
      POSTGRES_PASSWORD: "myPassw0rd"
      POSTGRES_DB: "SearchPortal"
    volumes:
      - pgdata:/var/lib/postgresql/data
    networks:
      - abp-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 10s
      retries: 5
  
  # Added a UI to be able to view the database
  pgadmin:
    image: dpage/pgadmin4
    container_name: pgadmin
    environment:
      PGADMIN_DEFAULT_EMAIL: "pgadmin4@pgadmin.org"
      PGADMIN_DEFAULT_PASSWORD: "admin"
    ports:
      - "5050:80"
    volumes:
      - pgadmin-data:/var/lib/pgadmin
    networks:
      - abp-network
    depends_on:
      - postgres
    healthcheck:
      test: ["CMD-SHELL", "wget","-O","-","http://localhost:80/misc/ping"]
      interval: 10s
      timeout: 10s
      retries: 5

volumes:
  pgdata:
    name: searchportal_pgdata
  pgadmin-data:
    name: pgadmin-data

networks:
  abp-network:
    name: searchportal-network
    driver: bridge
  • ABP Framework version: v7.2.2

  • UI type: Blazor Server

  • DB provider: EF Core / Postgress

  • Tiered (MVC) or Identity Server Separated (Angular): no

  • Exception message and stack trace: Severity Code Description Project File Line Suppression State Error (active) 0 Incorrect type. Expected "array | docker-compose.yml C:...aspnet-core\etc\docker\docker-compose.yml 20

  • Steps to reproduce the issue:"

Hi

We are having problems connecting SignalR to the public MVC page and are getting the following error

We have successfully been using SignalR for our Blazor WASM backend (hosted as static website in Azure) so we know all about how SignalR should work (or we thought at least).

We have been trying all kinds versions of CORS settings in HttpApi.Host without luck

This didn´t do anything (now we are just using app.UseCors())

  app.UseCors(x => x
           .AllowAnyMethod()
           .AllowAnyHeader()
           .SetIsOriginAllowed(origin => true)
           .AllowCredentials());

Is there a documentation or some other steps that we might be missing for for connecting with signalR in MVC public web app?

  • ABP Framework version: 7.0.2
  • UI type: MVC
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated: yes
Showing 1 to 10 of 33 entries
Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11