Starts in:
2 DAYS
11 HRS
15 MIN
42 SEC
Starts in:
2 D
11 H
15 M
42 S

Activities of "cangunaydin"

  • ABP Framework version: v7.4.0
  • UI Type: Angular
  • Database System: EF Core (SQL Server, Oracle, MySQL, PostgreSQL, etc..)

Hello, I recently upgraded my abp version from 7.3.2 to 7.4.0, I don't know if this is related with upgrade, maybe this wasn't working fine before.

In angular part of the gdpr module, when i look at the source code, it checks the cookie consent, if it is true it doesn't show the accept cookie bar as I understand.

here is the code for checking the cookie, here cookie key is '.AspNet.Consent'

 protected checkCookieConsent() {
    const hasCookieConsent =
      decodeURIComponent(this.document.cookie)
        .split(' ')
        .indexOf(this.cookieKey + '=true') > -1;

    if (hasCookieConsent) {
      this.showCookieConsent = false;
    }
  }

When i look at my cookies on chrome,I can see that it is true.

when i debug this, i can see that array from the code decodeURIComponent(this.document.cookie.split(' ') has an item like

here you can see indexOf shouldn't be .indexOf(this.cookieKey + '=true') but it should be .indexOf(this.cookieKey + '=true;') to make it work (';' semicolon at the end). I use chrome by the way. Maybe it works with other browsers, i didn't test it with others. Is there any trick that I can do to fix it fast?

  • ABP Framework version: v7.4.0
  • UI Type: Angular
  • Database System: EF Core (SQL Server, Oracle, MySQL, PostgreSQL, etc..)
  • Tiered (for MVC) or Auth Server Separated (for Angular): yes

Hello I recently upgraded to Abp v7.4.0, I am using file management module with abp, I customize it according to my needs and it was working fine. Now i have a problem with file download. I think there is a bug related with it. Since i customize it i couldn't be sure but I didn't override download part before, so it is likely from the new version.

Anyway here is the problem. For download to work first angular is doing a backend call to get a token. Then doing get request by using javascript window.open here is the file management module angular code.

  downloadFile(file: FileInfo) {
    return this.fileDescriptorService.getDownloadToken(file.id).pipe(
      tap((res) => {
        window.open(
          `${this.apiUrl}/api/file-management/file-descriptor/download/${file.id}?token=${res.token}`,
          '_self'
        );
      })
    );
  }

"this.fileDescriptorService.getDownloadToken" call is an authenticated but file-descriptor/download call is anonymous call.

On the backend side, when IDistributedCache is used it sets the token for the current tenant. so it normalizes the cache key. here is the code for it.

 public virtual async Task<DownloadTokenResultDto> GetDownloadTokenAsync(Guid id)
 {
     var token = Guid.NewGuid().ToString();

     await DownloadTokenCache.SetAsync(
         token,
         new FileDownloadTokenCacheItem { FileDescriptorId = id },
         new DistributedCacheEntryOptions
         {
             AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(60)
         });

     return new DownloadTokenResultDto
     {
         Token = token
     };
 }

here the current tenant id is set. So the problem is when you do the second call to /api/file-management/file-descriptor/download/ endpoint with window.open since it is anonymous and token is not set it doesn't get the current tenant id. here is the code for it.

 [AllowAnonymous]
 public virtual async Task<IRemoteStreamContent> DownloadAsync(Guid id, string token)
 {
     var downloadToken = await DownloadTokenCache.GetAsync(token);
     if (downloadToken == null || downloadToken.FileDescriptorId != id)
     {
         throw new AbpAuthorizationException("Invalid download token: " + token);
     }

     FileDescriptor fileDescriptor;
     using (DataFilter.Disable<IMultiTenant>())
     {
         fileDescriptor = await FileDescriptorRepository.GetAsync(id);
     }
     var stream = await BlobContainer.GetAsync(id.ToString());
     return new RemoteStreamContent(stream, fileDescriptor?.Name);
 }

here you get authorization exception since cache key is not normalized over here. even if i override and change the current tenant id to null, it gets the token but this time BlobContainer can not find the file since this file belongs to tenant. What i came up with is to send tenantId from user interface as a query string and override FileDescriptorController like this.

also i override the angular part and inject the new service as a download service. sth like

@Injectable()
export class CreativeDownloadService {
  apiName = 'FileManagement';

  get apiUrl() {
    return this.environment.getApiUrl(this.apiName);
  }

  constructor(
    private restService: RestService,
    private fileDescriptorService: FileDescriptorService,
    private environment: EnvironmentService,
    private configStateService: ConfigStateService
  ) {}

  downloadFile(file: FileInfo) {
    const currentUser = this.configStateService.getOne("currentUser"); 
    return this.fileDescriptorService.getDownloadToken(file.id).pipe(
      tap((res) => {
        window.open(
          `${this.apiUrl}/api/file-management/file-descriptor/download/${file.id}?token=${res.token}&__tenant=${currentUser?.tenantId}`,
          '_self'
        );
      })
    );
  }
}

and then provide it.

I don't know how this was working before. I wonder if new version changed sth, by the way i use redis cache. Also sth I didn't understand is according to docs

giving query string __tenant should set CurrentTenant but it doesn't do so. Is this related with [AllowAnonymous] attribute? Thanks for the help and waiting for your reply.

  • ABP Framework version: v7.1.0
  • UI type: Angular
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes

Hello, I am trying to implement hangfire to my project. I managed to do that, the only problem that i have is with hangfire dashboard. If i do not use authentication for my hangfire dashboard it works fine. And i can access it. But when i have enabled the filter, i can not access the page. In HttpContext i can not see the user claims, so it return unauthenticated inside AbpHangfireAuthorizationFilter.

I logged in with admin rights and when i call a method from swagger endpoint i can see that claims are there for user and CurrentUser.IsAuthenticated property returns true. I couldn't understand why current user is unauthenticated (or claims are not in the context) when AbpHangfireAuthorizationFilter is triggered. any tips about it?

here is the onApplicationInitialization

  public override void OnApplicationInitialization(ApplicationInitializationContext context)
    {
        var app = context.GetApplicationBuilder();
        var env = context.GetEnvironment();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseAbpRequestLocalization();
        app.UseStaticFiles();
        app.UseAbpSecurityHeaders();
        app.UseRouting();
        app.UseCors();
        app.UseAuthentication();

        if (MultiTenancyConsts.IsEnabled)
        {
            app.UseMultiTenancy();
        }

        app.UseAuthorization();
        app.UseSwagger();
        app.UseAbpSwaggerUI(options =>
        {
            options.SwaggerEndpoint("/swagger/v1/swagger.json", "Doohlink API");

            var configuration = context.GetConfiguration();
            options.OAuthClientId(configuration["AuthServer:SwaggerClientId"]);
        });
        app.UseAuditing();
        app.UseAbpSerilogEnrichers();
        app.UseUnitOfWork();
        app.UseHangfireDashboard("/hangfire", new DashboardOptions
        {
            AsyncAuthorization = new[] { new DoohlinkAuthorizationFilter() }
        });
        app.UseConfiguredEndpoints();

    }

ps: to see the httpcontext I have changed AbpHangfireAuthorizationFilter to custom class inside my project here is DoohlinkAuthorizationFilter

public class DoohlinkAuthorizationFilter : IDashboardAsyncAuthorizationFilter
{
    private readonly bool _enableTenant;
    private readonly string _requiredPermissionName;

    public DoohlinkAuthorizationFilter(bool enableTenant = false, string requiredPermissionName = null)
    {
        _enableTenant = requiredPermissionName.IsNullOrWhiteSpace() ? enableTenant : true;
        _requiredPermissionName = requiredPermissionName;
    }

    public async Task<bool> AuthorizeAsync(DashboardContext context)
    {
        if (!IsLoggedIn(context, _enableTenant))
        {
            return false;
        }

        if (_requiredPermissionName.IsNullOrEmpty())
        {
            return true;
        }

        return await IsPermissionGrantedAsync(context, _requiredPermissionName);
    }

    private static bool IsLoggedIn(DashboardContext context, bool enableTenant)
    {
        var currentUser = context.GetHttpContext().RequestServices.GetRequiredService<ICurrentUser>();

        if (!enableTenant)
        {
            return currentUser.IsAuthenticated && !currentUser.TenantId.HasValue;
        }

        return currentUser.IsAuthenticated;
    }

    private static async Task<bool> IsPermissionGrantedAsync(DashboardContext context, string requiredPermissionName)
    {
        var permissionChecker = context.GetHttpContext().RequestServices.GetRequiredService<IPermissionChecker>();
        return await permissionChecker.IsGrantedAsync(requiredPermissionName);
    }
}

and this is httpcontext quickwatch

  • ABP Framework version: v7.1.0
  • UI type: Angular
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes
  • Exception message and stack trace:

System.InvalidOperationException: Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct. at System.Collections.Generic.Dictionary2.TryInsert(TKey key, TValue value, InsertionBehavior behavior) at System.Collections.Generic.Dictionary2.set_Item(TKey key, TValue value) at Volo.Abp.Uow.UnitOfWorkExtensions.GetOrAddItem[TValue](IUnitOfWork unitOfWork, String key, Func2 factory) at Volo.Abp.Caching.DistributedCache2.GetAsync(TCacheKey key, Nullable1 hideErrors, Boolean considerUow, CancellationToken token) at Volo.Saas.Tenants.TenantStore.GetCacheItemAsync(Nullable1 id, String name) at Volo.Saas.Tenants.TenantStore.FindAsync(Guid id) at Volo.Abp.MultiTenancy.MultiTenantConnectionStringResolver.FindTenantConfigurationAsync(Guid tenantId) at Volo.Abp.MultiTenancy.MultiTenantConnectionStringResolver.ResolveAsync(String connectionStringName) at Volo.Abp.Uow.EntityFrameworkCore.UnitOfWorkDbContextProvider1.ResolveConnectionStringAsync(String connectionStringName) at Volo.Abp.Uow.EntityFrameworkCore.UnitOfWorkDbContextProvider1.GetDbContextAsync() at Volo.Abp.Domain.Repositories.EntityFrameworkCore.EfCoreRepository2.GetDbSetAsync() at Volo.Abp.Domain.Repositories.EntityFrameworkCore.EfCoreRepository2.GetQueryableAsync() at Volo.Abp.Domain.Repositories.EntityFrameworkCore.EfCoreRepository2.WithDetailsAsync() at Volo.Abp.Domain.Repositories.EntityFrameworkCore.EfCoreRepository3.FindAsync(TKey id, Boolean includeDetails, CancellationToken cancellationToken) at Volo.Abp.Domain.Repositories.EntityFrameworkCore.EfCoreRepository3.GetAsync(TKey id, Boolean includeDetails, CancellationToken cancellationToken) at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func3 proceed) at Doohlink.CampaignManagement.Screens.ScreenAppService.GetAsync(Guid id) in C:\Development\Projects\Examples\Doohlink\aspnet-core\modules\Doohlink.CampaignManagement\src\Doohlink.CampaignManagement.Application\Screens\ScreenAppService.cs:line 22 at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Authorization.AuthorizationInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func3 proceed) at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.GlobalFeatures.GlobalFeatureInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func3 proceed) at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Auditing.AuditingInterceptor.ProceedByLoggingAsync(IAbpMethodInvocation invocation, AbpAuditingOptions options, IAuditingHelper auditingHelper, IAuditLogScope auditLogScope) at Volo.Abp.Auditing.AuditingInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func3 proceed) at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Validation.ValidationInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func3 proceed) at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed) at Doohlink.Screens.ScreenAppService.GetAsync(Guid id) in C:\Development\Projects\Examples\Doohlink\aspnet-core\src\Doohlink.Application\Screens\ScreenAppService.cs:line 23

Hello, I have an application which i created two different modules and from the main app i am calling application services of those modules async methods in parallel. sth like this.

 public async Task&lt;ScreenDto&gt; GetAsync(Guid id)
    {
        var inventory = _inventoryScreenAppService.GetAsync(id);
        var campaign = _campaignScreenAppService.GetAsync(id);
        await Task.WhenAll(inventory, campaign);

        var screenDto = new ScreenDto();
        ObjectMapper.Map(inventory.Result, screenDto);
        ObjectMapper.Map(campaign.Result, screenDto);

        return screenDto;
    }

not always but sometimes I am getting this exception on runtime. It is very straightforward what happens inside those 2 appservices.

Inventory ScreenAppService

   public async Task&lt;ScreenDto&gt; GetAsync(Guid id)
    {
        var screen = await _screenRepository.GetAsync(id);
        return ObjectMapper.Map&lt;Screen, ScreenDto&gt;(screen);
    }

Campaign ScreenAppService

 public async Task&lt;ScreenDto&gt; GetAsync(Guid id)
    {
        var screen = await _screenRepository.GetAsync(id);
        return ObjectMapper.Map&lt;Screen, ScreenDto&gt;(screen);
    }

two modules have different dbcontexts(2 seperate databases). and storing different information about screen. it seems it is the same method but they are in different namespaces and different properties they hold for screen and screendto.

Campaign ScreenDto

using System;
using System.Collections.Generic;
using Volo.Abp.Application.Dtos;

namespace Doohlink.CampaignManagement.Screens;

public class ScreenDto : EntityDto&lt;Guid&gt;
{
    public ResolutionDto Resolution { get; set; }

    public List&lt;OpeningHoursDto&gt; OpeningHours { get; set; }

    public List&lt;double&gt; Durations { get; set; }

    public List&lt;string&gt; MimeTypes { get; set; }
}

Inventory ScreenDto

using System;
using Volo.Abp.Application.Dtos;

namespace Doohlink.InventoryManagement.Screens;

public class ScreenDto : EntityDto&lt;Guid&gt;
{
    public string Name { get; set; }

    public string MacAddress { get; set; }

    public LocationDto Location { get; set; }
}

as I see from the exception it is trying to get the tenant and resolve the configuration

at System.Collections.Generic.Dictionary2.TryInsert(TKey key, TValue value, InsertionBehavior behavior) at System.Collections.Generic.Dictionary2.set_Item(TKey key, TValue value) at Volo.Abp.Uow.UnitOfWorkExtensions.GetOrAddItem[TValue](IUnitOfWork unitOfWork, String key, Func2 factory) at Volo.Abp.Caching.DistributedCache2.GetAsync(TCacheKey key, Nullable1 hideErrors, Boolean considerUow, CancellationToken token) at Volo.Saas.Tenants.TenantStore.GetCacheItemAsync(Nullable1 id, String name) at Volo.Saas.Tenants.TenantStore.FindAsync(Guid id) at Volo.Abp.MultiTenancy.MultiTenantConnectionStringResolver.FindTenantConfigurationAsync(Guid tenantId)

it seems it is a concurrency issue while tenant has been fetched from the cache or db. Any suggestion to fix this issue?

Ps: I have tried to change the method in main app

 public async Task&lt;ScreenDto&gt; GetAsync(Guid id)
    {
        var inventory = _inventoryScreenAppService.GetAsync(id);
        var campaign = _campaignScreenAppService.GetAsync(id);
        await Task.WhenAll(inventory, campaign);

        var screenDto = new ScreenDto();
        ObjectMapper.Map(inventory.Result, screenDto);
        ObjectMapper.Map(campaign.Result, screenDto);

        return screenDto;
    }

to

 public async Task&lt;ScreenDto&gt; GetAsync(Guid id)
    {
        var inventory =await _inventoryScreenAppService.GetAsync(id);
        var campaign =await _campaignScreenAppService.GetAsync(id);
        

        var screenDto = new ScreenDto();
        ObjectMapper.Map(inventory, screenDto);
        ObjectMapper.Map(campaign, screenDto);

        return screenDto;
    }

it didn't fix the issue.

  • ABP Framework version: v7.1.0
  • UI type: Angular
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes

Hello, I am trying to understand how the localization works for the leptonx theme since i am getting the warning in my angular app 'Could not find localization source: LeptonX'

if i debug the app here you can see it tries to get the localization value from source LeptonX. But there is no such resource inside the source list.

What i wonder is, how does the angular leptonx module is taking the resource from the backend? If you create a solution from scratch with angular, it doesn't include the leptonx module inside HttpApi.Host project

shouldn't it include the localization resource so it can find it inside resources for angular app?

  • ABP Framework version: v7.0.3
  • UI type: Angular
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes
  • Exception message and stack trace:
  • Steps to reproduce the issue:"

Hello. I have 2 questions that i couldn't understand. I use abp cli 7.0.3

  1. I have created a brand new app from scratch with -t app-pro template with this cli command

abp new Doohlink -t app-pro -u angular -dbms PostgreSQL --separate-auth-server -m maui -csf

If i want to do npm install inside angular folder i got an error about peerdependency here is the short version of the error.

Could not resolve dependency: peer @ng-bootstrap/ng-bootstrap@"12.1.2" from @volosoft/abp.ng.theme.lepton-x@2.0.4 node_modules/@volosoft/abp.ng.theme.lepton-x @volosoft/abp.ng.theme.lepton-x@"^2.0.0-rc.2" from the root project

Conflicting peer dependency: @ng-bootstrap/ng-bootstrap@12.1.2 node_modules/@ng-bootstrap/ng-bootstrap peer @ng-bootstrap/ng-bootstrap@"12.1.2" from @volosoft/abp.ng.theme.lepton-x@2.0.4 node_modules/@volosoft/abp.ng.theme.lepton-x @volosoft/abp.ng.theme.lepton-x@"^2.0.0-rc.2" from the root project

Fix the upstream dependency conflict, or retry this command with --force or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution.

when i do yarn it executes and if i do yarn start everything works fine. What is the reason behind this should i use yarn all the time and why npm is having problems?

  1. if i want to add a module with abp add-module command then i can not build those projects with ng build command. here is the command that i use.

abp add-module Doohlink.CreativeManagement --new -t module-pro --add-to-solution-file --startup-project .\aspnet-core\src\Doohlink.HttpApi.Host\Doohlink.HttpApi.Host.csproj -s .\aspnet-core\Doohlink.sln

when i try to run

ng build creative-management

it gives me an error.

Error: Could not find the '@angular-devkit/build-ng-packagr:build' builder's node package.

"@angular-devkit/build-angular": "^15.0.1", is inside my dev dependencies. and i can see it inside node-modules folder.

is this a bug? or am i doing sth wrong over here? Thank you.

  • ABP Framework version: v7.0.1
  • UI type: Angular
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes
  • Exception message and stack trace:
  • Steps to reproduce the issue:"

Hello, I am trying to use Dev extreme scheduler in my angular app. I am using commercial module with leptonx theme but behavior is the same for leptonx lite. When DxScheduler is rendered initially, it becomes unresponsive and styles are broken inside of it. here is the picture of how it looks.

normally it should look like this.

if you do window resize, click a button or if you load another page first and then switch to the page where scheduler is implemented then it renders the component again and it works fine. But when you refresh the page that the scheduler is included it breaks again. Probably some style is conflicting with devx styles.

To reproduce the issue you can follow these steps.

  1. Create new app from scratch, abp new Acme.BookStore -t app -u angular -m none --separate-auth-server --database-provider ef -csf
  2. On angular project, just follow the guidelines of devx getting started (https://js.devexpress.com/Documentation/Guide/Angular_Components/Getting_Started/Add_DevExtreme_to_an_Angular_CLI_Application/) which is.
    • add devx packages. yarn add devextreme@22.2 devextreme-angular@22.2
    • then add devx style to angular.json
    • add dx-viewport class to body.
    • add DxSchedulerModule to module imports in HomeModule
  3. Afterwards i have implemented this demo from devx angular demos. (https://js.devexpress.com/Demos/WidgetsGallery/Demo/Scheduler/SimpleArray/Angular/Light/) which looks like this. here is the home.component.ts
    import { AuthService } from '@abp/ng.core';
import { Component } from '@angular/core';
import { FakeAppointmentService } from '../services/fake-appointment.service';
import { Appointment } from '../services/fake-appointment.service';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss'],
})
export class HomeComponent {
  appointmentsData: Appointment[] = [];

  currentDate: Date = new Date(2021, 2, 28);

  get hasLoggedIn(): boolean {
    return this.authService.isAuthenticated;
  }

  constructor(private authService: AuthService, private fakeService: FakeAppointmentService) {
    this.appointmentsData = fakeService.getAppointments();
  }

  login() {
    this.authService.navigateToLogin();
  }
}

and here is the fake-appointment.service.ts

import { Injectable } from '@angular/core';

export class Appointment {
  text: string;

  startDate: Date;

  endDate: Date;

  allDay?: boolean;
}

const appointments: Appointment[] = [
  {
    text: 'Website Re-Design Plan',
    startDate: new Date('2021-03-29T16:30:00.000Z'),
    endDate: new Date('2021-03-29T18:30:00.000Z'),
  }, {
    text: 'Book Flights to San Fran for Sales Trip',
    startDate: new Date('2021-03-29T19:00:00.000Z'),
    endDate: new Date('2021-03-29T20:00:00.000Z'),
    allDay: true,
  }, {
    text: 'Install New Router in Dev Room',
    startDate: new Date('2021-03-29T21:30:00.000Z'),
    endDate: new Date('2021-03-29T22:30:00.000Z'),
  }, {
    text: 'Approve Personal Computer Upgrade Plan',
    startDate: new Date('2021-03-30T17:00:00.000Z'),
    endDate: new Date('2021-03-30T18:00:00.000Z'),
  }, {
    text: 'Final Budget Review',
    startDate: new Date('2021-03-30T19:00:00.000Z'),
    endDate: new Date('2021-03-30T20:35:00.000Z'),
  }, {
    text: 'New Brochures',
    startDate: new Date('2021-03-30T21:30:00.000Z'),
    endDate: new Date('2021-03-30T22:45:00.000Z'),
  }, {
    text: 'Install New Database',
    startDate: new Date('2021-03-31T16:45:00.000Z'),
    endDate: new Date('2021-03-31T18:15:00.000Z'),
  }, {
    text: 'Approve New Online Marketing Strategy',
    startDate: new Date('2021-03-31T19:00:00.000Z'),
    endDate: new Date('2021-03-31T21:00:00.000Z'),
  }, {
    text: 'Upgrade Personal Computers',
    startDate: new Date('2021-03-31T22:15:00.000Z'),
    endDate: new Date('2021-03-31T23:30:00.000Z'),
  }, {
    text: 'Customer Workshop',
    startDate: new Date('2021-04-01T18:00:00.000Z'),
    endDate: new Date('2021-04-01T19:00:00.000Z'),
    allDay: true,
  }, {
    text: 'Prepare 2021 Marketing Plan',
    startDate: new Date('2021-04-01T18:00:00.000Z'),
    endDate: new Date('2021-04-01T20:30:00.000Z'),
  }, {
    text: 'Brochure Design Review',
    startDate: new Date('2021-04-01T21:00:00.000Z'),
    endDate: new Date('2021-04-01T22:30:00.000Z'),
  }, {
    text: 'Create Icons for Website',
    startDate: new Date('2021-04-02T17:00:00.000Z'),
    endDate: new Date('2021-04-02T18:30:00.000Z'),
  }, {
    text: 'Upgrade Server Hardware',
    startDate: new Date('2021-04-02T21:30:00.000Z'),
    endDate: new Date('2021-04-02T23:00:00.000Z'),
  }, {
    text: 'Submit New Website Design',
    startDate: new Date('2021-04-02T23:30:00.000Z'),
    endDate: new Date('2021-04-03T01:00:00.000Z'),
  }, {
    text: 'Launch New Website',
    startDate: new Date('2021-04-02T19:20:00.000Z'),
    endDate: new Date('2021-04-02T21:00:00.000Z'),
  },
];
@Injectable({
  providedIn: 'root'
})
export class FakeAppointmentService {

  constructor() { }
  getAppointments(): Appointment[] {
    return appointments;
  }
}

by the way when i do the same steps with new angular app from angular cli, it works perfectly so probably sth is wrong when the leptonx theme is initializing. maybe some styles are overriding. Hope this was clear. Thank you for the assistance.

Hello, I have a case that i need to apply passwordless authentication for my project. I use seperated auth server with openiddict. What i want to do is,

  • get an email address from the user
  • check if that email address is in my database. (this is an email not stored in AbpUsers table)
  • if so create a code and send that code to user's email address.
  • Show a textbox for verification
  • if the user input is the same with the code sent, sign in the user.
  • Apply refreshtoken when the login is expired.

Is there any code sample so i can take a look or any resources that i can use? I was thinking to extend the Login page from Volo.Abp.Account.Pro.Public.Web. Is sth else needed like Extending authorize method of OpenIdDict module? Also how should i think about refreshtoken in this case?

I have blazor web assembly front end and .net maui app that will use this kind of auth.

Thanks in advance.

Hello, I have come up to interesting video on youtube from Mauro Servienti. In his presentation he was explaining, about different bounded contexts responsible for different parts of the application. But he used view model composition and decomposition while building the user interface. This makes the solution interesting. Interesting part was each different module wasn't owning the user interface since view was composed from different bounded contexts of the application. https://www.youtube.com/watch?v=KkzvQSuYd5I

So in abp, mostly when you create a bounded context, I automatically think that view should also belong to that module (bounded context). Let me give you an example I was playing around.

I have Product Aggregate which consists of

Product: Aggregate Root

Id: Guid Name: string Description:string StockQuantity:int Price: decimal

also i have Order aggregate which consists of

Order: Aggregate Root

Id:Guid Name: string Items: List<OrderItem> TotalValue:decimal

OrderItem : Entity

Id:Guid OrderId:Guid ProductId:Guid Price: decimal Quantity: decimal Subtotal: decimal

So i wanted to seperate this to two bounded contexts Which is "inventory bounded context" and "sales bounded context". I know that Product in "Sales Bounded Context" and "Inventory Bounded Context" are not the same. In "Sales Bounded Context" i am not interested in how many items are in the stock.

So here the problem arises when i want to create the user interface in "Sales Bounded Context" to create an order. Since I do not know anything about Product, how am i going to list the products here? Two solutions i can think of.

Whenever product is created or updated or deleted on "Inventory bounded context" I will handle that event and create aggregate on "Sales bounded context". So i will copy the product information needed to my "Sales bounded context". Then i can use that in "Sales bounded context".

Second solution is to use IProductAppService in presentation layer of "Sales Bounded Context" which will list the products. This means i need to give the reference to HttpApi.Client project of "Inventory Bounded Context" module. (I don't know what kind of problems does this make? am i coupling my code to the other bounded context?)

Mauro Servienti in the video is giving another solution which says that, presentation layer should be another project which will compose and decompose those bounded contexts which is "inventory bounded context" and "sales bounded context"

So i am pretty confused which way is gonna be the right way. Before I watched the video i was more leaning into copying the products on the "sales bounded context" since it has different properties in that context. Do you have any suggestions how to move forward in these cases? Any advice will be much appreciated. Thank you for reading it.

  • ABP Framework version: v5
  • UI type: MVC
  • DB provider: EF Core

Hello, I am new to Abp structure and i was checking out the docs for microservice structure, i have created a sample solution from abp suite. And i was going through the docs and trying to understand how the system works. I believe on the previous version, solution was using internal gateway to do the communication between services. Why was it removed in this version? Actually i am not sure what was the internal gateway was doing on the previous version. was it only a gateway that is publishing the events from rabbitmq and do the communication between all micro-services? And if it was doing all the communication between all microservices before right now how it has been solved? And i believe only "administration service" needs to make a call to "identity service", is there any other microservice making a call to other microservices?

I think all the built-in modules coming from Abp are now using static http client generation explained here: https://github.com/abpframework/abp/blob/dev/docs/en/Blog-Posts/2021-11-18%20v5_0_Preview/POST.md#static-generated-client-proxies-for-c-and-javascript I understand that administration service need to talk to identityservice and this is done with static http client proxies now. But what i don't understand is why administrationservice needs to depend on 5 contractsmodule which are

AbpAccountAdminApplicationContractsModule AbpAccountPublicApplicationContractsModule ProductServiceApplicationContractsModule SaasServiceApplicationContractsModule IdentityServiceApplicationContractsModule

i couldn't see anything on the documentation why these are needed maybe i am missing sth over here maybe it is related with static http client proxies. Maybe these are kind of basic questions but i am new to microservice concept and new abp structure. I would be glad if you could clarify those points for me.

ps: still on the doc it mentions about internal gateway which is not present probably it would be modified when the v5 is released. https://docs.abp.io/en/commercial/5.0/startup-templates/microservice/microservices#administrationservice

Showing 21 to 30 of 30 entries
Made with ❤️ on ABP v9.1.0-preview. Updated on November 20, 2024, 13:06