.net core/ 9.1.0 / Angular
We are running our App in West Europe and France Central regions on Azure.
In 80% cases, downloading a file with FileDownloadService
works perfectly well.
In 20% cases, I get the following error in browser with white page:
{"result":"Requested file does not exist!","targetUrl":null,"success":true,"error":null,"unAuthorizedRequest":false,"__abp":true}
Hi @ismcagdas, Are you able to reproduce the issue?
Hi @ismcagdas,
I shared the email. You can download the code from my onedrive link: https://1drv.ms/u/s!AlmThg0xqW35grc9Q5nf4Usz4QLU0Q?e=uPiFPH
I'll delete this source code on 15th April.
Hi @ismcagdas,
I have shared the angular project with minimal code to reproduce the issue :)
Added in /angular/src/app/main/order-mapping
@ismcagdas, I commented this code and then realized that it is the same issue with all lazy loaded modules
product-mapping.module.ts
import { NgModule } from '@angular/core';
import { PaginatorModule } from 'primeng/paginator';
import { TableModule } from 'primeng/table';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { NgxDnDModule } from '@node_modules/@swimlane/ngx-dnd';
import { ModalModule } from 'ngx-bootstrap/modal';
import { TooltipModule } from 'ngx-bootstrap/tooltip';
import { NgArrayPipesModule } from '@node_modules/ngx-pipes';
import { UtilsModule } from '@shared/utils/utils.module';
import {
ProductMappingRoutingModule,
routedComponents
} from '@app/main/product-mapping/product-mapping.routing.module';
import { AppCommonModule } from '@app/shared/common/app-common.module';
import { DefaultProductMapperModalComponent } from '@app/main/product-mapping/default-product-mapper/default-product-mapper-modal.component';
@NgModule({
imports: [
FormsModule,
CommonModule,
AppCommonModule,
TableModule,
PaginatorModule,
TooltipModule,
ModalModule,
NgxDnDModule,
UtilsModule,
NgArrayPipesModule,
ProductMappingRoutingModule
],
declarations: [routedComponents, DefaultProductMapperModalComponent],
exports: [],
providers: []
})
export class ProductMappingModule {}
product-mapping.routing.module.ts
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { ProductMappingComponent } from './product-mapping.component';
const routes: Routes = [{ path: '', component: ProductMappingComponent }];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ProductMappingRoutingModule {}
export const routedComponents = [ProductMappingComponent];
product-mapping.component.ts
import { ChangeDetectorRef, Component, Injector, OnInit, ViewChild } from '@angular/core';
import { AppComponentBase } from 'shared/common/app-component-base';
import { appModuleAnimation } from 'shared/animations/routerTransition';
import {
InstalledLogisticProviderDto,
LogisticProviderCustomersServiceProxy,
PrimePenguinAdminCommonServiceProxy,
PrimePenguinCommonServiceProxy,
ProductMappingDto,
ProductMappingServiceProxy
} from 'shared/service-proxies/service-proxies';
import { LazyLoadEvent, Table, Paginator } from 'primeng';
import { flatMap } from 'lodash';
import { finalize, map } from 'rxjs/operators';
import {
AddUpdateProductMappingsInput,
LogisticProviderCustomerTenantIdNameDto,
MappingConfigurationDto
} from '@shared/service-proxies/service-proxies';
import { AppConsts } from '@shared/AppConsts';
import { MappingConfigurationType } from '@shared/service-proxies/service-proxies';
@Component({
templateUrl: './product-mapping.component.html',
animations: [appModuleAnimation()]
})
export class ProductMappingComponent extends AppComponentBase implements OnInit {
@ViewChild('dataTable', {static: true}) dataTable: Table;
@ViewChild('paginator', {static: true}) paginator: Paginator;
filter = '';
isAdmin;
isEshop;
isLogisticProvider;
mappingConfigurationTypes = AppConsts.mappingConfigurationTypes.filter(c => c.id !== MappingConfigurationType.Default);
defaultPriority = AppConsts.fixedValues.maxShort;
logisticProviderId = '';
customerTenantId = '';
logisticProviders: InstalledLogisticProviderDto[] = [];
customers: LogisticProviderCustomerTenantIdNameDto[] = [];
changedVariantMappings: { productVariantId: number; customerTenantId: number }[] = [];
constructor(
injector: Injector,
private _productMappingService: ProductMappingServiceProxy,
private _commonService: PrimePenguinCommonServiceProxy,
private _adminCommonService: PrimePenguinAdminCommonServiceProxy,
private _lpCustomerService: LogisticProviderCustomersServiceProxy,
private _cd: ChangeDetectorRef
) {
super(injector);
}
ngOnInit() {
this.isEshop = this.permission.isGranted(AppConsts.ppPermissions.salesChannelUser);
this.isLogisticProvider = this.permission.isGranted(AppConsts.ppPermissions.logisticProviderAdmin);
this.isAdmin = this.permission.isGranted(AppConsts.ppPermissions.admin.all);
if (this.isAdmin) {
this._adminCommonService.getAllLogisticProviders().subscribe(result => (this.logisticProviders = result.items));
this._commonService.getLogisticProviderCustomers(undefined).subscribe(result => (this.customers = result));
}
if (this.isLogisticProvider) {
this._lpCustomerService
.getAll(undefined)
.pipe(
map(result =>
result.items.map(
c =>
new LogisticProviderCustomerTenantIdNameDto({
id: c.customerTenantId,
name: c.customerTenantName
})
)
)
)
.subscribe(result => (this.customers = result));
}
}
getLogisticProviderId = () => (+this.logisticProviderId > 0 ? +this.logisticProviderId : undefined);
getCustomerTenantId = () => {
if (this.isAdmin || this.isLogisticProvider) {
return +this.customerTenantId > 0 ? +this.customerTenantId : undefined;
}
if (this.isEshop) {
return abp.session.tenantId;
}
return undefined;
};
isDefaultMappingSelected = mapping => MappingConfigurationType.Default === +mapping;
markVariantAsChanged = (productVariantId: number, customerTenantId: number) => {
const existing = this.changedVariantMappings.filter(
c => c.customerTenantId === customerTenantId && c.productVariantId === productVariantId
);
if (existing.length > 0) {
return;
}
this.changedVariantMappings.push({ productVariantId, customerTenantId });
};
onMappingMove(productVariantId: number, customerTenantId: number) {
this.markVariantAsChanged(productVariantId, customerTenantId);
const movedConfig = (<ProductMappingDto[]>this.primengTableHelper.records).filter(
c => c.productVariantId === productVariantId && c.customerTenantId === customerTenantId
)[0];
movedConfig.mappingConfigurationDtos
.filter(c => c.mappingConfigurationType !== MappingConfigurationType.Default)
.forEach((c, i) => (c.mappingPriority = i + 1));
this._cd.detectChanges();
}
private getVariantById(productVariantId: number, customerTenantId: number): ProductMappingDto {
const variantIndex = (<ProductMappingDto[]>this.primengTableHelper.records).findIndex(
c => c.productVariantId === productVariantId && c.customerTenantId === customerTenantId
);
return this.primengTableHelper.records[variantIndex];
}
removeMapping(productVariantId: number, customerTenantId: number, mapping: MappingConfigurationDto) {
const variant = this.getVariantById(productVariantId, customerTenantId);
variant.mappingConfigurationDtos = variant.mappingConfigurationDtos.filter(c => c !== mapping);
this.onMappingMove(productVariantId, customerTenantId);
}
addMapping(productVariantId: number, customerTenantId: number) {
const variant = this.getVariantById(productVariantId, customerTenantId);
const defaultMapping = variant.mappingConfigurationDtos.filter(
c => c.mappingConfigurationType === MappingConfigurationType.Default
)[0];
const map = this.mappingConfigurationTypes[0];
const newMapping = new MappingConfigurationDto({
...defaultMapping,
mappingConfigurationType: map.id,
mappingConfigurationTypeName: map.name,
mappingPriority: 100,
id: undefined
});
variant.mappingConfigurationDtos = variant.mappingConfigurationDtos.concat(newMapping);
this.onMappingMove(productVariantId, customerTenantId);
}
getProductMappings(event?: LazyLoadEvent) {
if (this.primengTableHelper.shouldResetPaging(event)) {
this.paginator.changePage(0);
return;
}
this.changedVariantMappings = [];
this.primengTableHelper.showLoadingIndicator();
this._productMappingService
.getProductMappings(
this.getCustomerTenantId(),
this.getLogisticProviderId(),
this.filter,
this.primengTableHelper.getSorting(this.dataTable),
this.primengTableHelper.getMaxResultCount(this.paginator, event),
this.primengTableHelper.getSkipCount(this.paginator, event)
)
.pipe(finalize(() => this.primengTableHelper.hideLoadingIndicator()))
.subscribe(result => {
this.primengTableHelper.totalRecordsCount = result.totalCount;
this.primengTableHelper.records = result.items;
this.primengTableHelper.hideLoadingIndicator();
});
}
validateForm() {
const variants: ProductMappingDto[] = this.primengTableHelper.records;
const mappings = flatMap(variants, c => c.mappingConfigurationDtos);
if (mappings.some(c => !c.logisticProviderId)) {
return false;
}
if (mappings.some(c => !c.mappingConfigurationType)) {
return false;
}
return true;
}
addUpdateMappings(updatedMappings: ProductMappingDto[]) {
const changes: AddUpdateProductMappingsInput[] = [];
updatedMappings.forEach(m => {
m.mappingConfigurationDtos.forEach(c =>
changes.push(
new AddUpdateProductMappingsInput({
customerTenantId: m.customerTenantId,
productVariantId: m.productVariantId,
logisticProviderId: c.logisticProviderId,
mappingConfigurationType: <any>c.mappingConfigurationType,
mappingConfigurationValue: c.mappingConfigurationValue,
mappingPriority: c.mappingPriority
})
)
);
});
this._productMappingService.addUpdateProductMappings(changes).subscribe(() => {
this.notify.success(this.l('SavedSuccessfully'));
this.changedVariantMappings = [];
this.getProductMappings();
});
}
saveChanges(isInvalid: boolean) {
if (isInvalid || !this.validateForm()) {
this.message.error(this.l('FillAllDetails'));
return;
}
const variants: ProductMappingDto[] = this.primengTableHelper.records;
const updatedMappings = flatMap(
this.changedVariantMappings.map(m =>
variants.filter(c => c.productVariantId === m.productVariantId && c.customerTenantId === m.customerTenantId)
)
);
this.addUpdateMappings(updatedMappings);
}
}
Thanks :)
Hi @bobingham,
Here is my code for job:
public class ShipmentAddressLocationCoordinatesWorker : PeriodicBackgroundWorkerBase, ISingletonDependency
{
public ShipmentAddressLocationCoordinatesWorker(AbpTimer timer) : base(timer)
{
Timer.Period = 1000 * 60 * 60 * 24 * 7; // 7 Days
}
[UnitOfWork]
protected override void DoWork()
{
// My Code
}
}
and I initialize this with Hangfire as:
// At 1:50 of every 7th day
RecurringJob.AddOrUpdate<ShipmentAddressLocationCoordinatesWorker>(job => job.Start(), "50 1 * * 0", TimeZoneInfo.Utc);
This is also added in ApplicationModule's PostInitialize
function
workManager.Add(IocManager.Resolve<ShipmentAddressLocationCoordinatesWorker>());
Am I doing something wrong here? Having 2 expressions for timer is really confusing. Can it be simplified?
In the example I posted above, can you provide information on when the DoWork
function will be executed in ShipmentAddressLocationCoordinatesWorker
? :)
At 1:50 of every 7th day ?