Activities of "Hon-Tre_IFS"

When creating a new tenant via the ABP Tenant Management API (POST /api/tenant-management/tenants) from an external application, the tenant and admin user are created successfully. However, after logging in as the newly created admin user, the user is unable to create additional users due to missing permissions or role assignment.

This suggests that role-to-user mapping is not being applied automatically during tenant creation when the API is called externally (e.g., from Postman, another service, or automated script), even though the same call works correctly when made via Swagger or ABP UI. here is the example payload we are passing from other abp application { "name": "Tenant30", "tenantType": 0, "editionId": "Basic", "activationState": 0, "adminEmailAddress": "itp@gmail.com", "adminPassword": "Password@123", "extraProperties": { "subscriptionPlan": 0, "contact": "09876543210", "adminName": "Vasudha Gurram", "tenantHostName": "T30", "adminEmail": "itp@gmail.com", "firstName": "Vasudha", "lastName": "Gurram", "description": null, "country": "India", "region": "HYD" } }

I'm encountering an issue with SendGrid email delivery in my application when deployed to Azure. The problem occurs specifically in a layered (multi-tier) architecture, while the same code works perfectly in a single-layer setup and also functions correctly in local development environments.

Do we need configure an Extra in Layred solution

For Your Referance I have added the code

namespace Hon.IFS.SiteManagement.SiteRiskIndices
{
    [RemoteService]
    public abstract class SiteRiskIndexAppService : SiteManagementAppService ,ITransientDependency
    {
        #region Initialization and Constructor
        private readonly RiskIndexManager _riskIndexManager;

        private readonly IRiskIndexRepository _riskIndexRepository; // Add this field

        public SiteRiskIndexAppService(IRiskIndexRepository riskIndexRepository, RiskIndexManager riskIndexManager) // Update constructor
        {
            _riskIndexManager = riskIndexManager;
            _riskIndexRepository = riskIndexRepository; // Initialize the repository
        }

        #endregion
        #region BUlK CREATE RISK INDICES
        [Authorize(SiteManagementPermissions.RiskIndices.Create)]
        public  async Task<List<RiskIndexDto>> CreateBulkRiskIndicesAsync(Guid siteId, List<Guid> buildingIds)
        {
            var random = new Random();
            var createdRiskIndices = new List<RiskIndexDto>();

            foreach (var buildingId in buildingIds)
            {
                // Generate random values with 2 decimal places for each field
                var communityRiskIndex = Math.Round(random.NextDouble() * 100, 2); // Define communityRiskIndex
                var neighbourhoodRiskIndex = Math.Round(random.NextDouble() * 100, 2); // Define neighbourhoodRiskIndex
                var buildingRiskIndex = Math.Round(random.NextDouble() * 100, 2);
                var buildingRiskIndexPercentage = 20;
                var historicalFireIncident = random.Next(0, 11); // Integer between 0-10
                var historicalFireIncidentPercentage = 10;
                var maintenance = Math.Round(random.NextDouble() * 100, 2);
                var maintenancePercentage = 10;
                var fireSupression = Math.Round(random.NextDouble() * 100, 2);
                var fireSupressionPercentage = 10;
                var fireService = Math.Round(random.NextDouble() * 100, 2);
                var fireServicePercentage = Math.Round(random.NextDouble() * 100, 2);
                var buildingOrg = Math.Round(random.NextDouble() * 100, 2);
                var buildingOrgPercentage = 10;
                var passiveFire = Math.Round(random.NextDouble() * 100, 2);
                var passiveFirePercentage = 10;
                var detection = Math.Round(random.NextDouble() * 100, 2);
                var detectionPercentage = 10;
                var ignition = Math.Round(random.NextDouble() * 100, 2);
                var ignitionPercentage = 10; // Ensure ignitionPercentage is included
                var riskIndexScore = (buildingRiskIndex * buildingRiskIndexPercentage)
                                    + (historicalFireIncident * historicalFireIncidentPercentage)
                                    + (maintenance * maintenancePercentage)
                                    + (fireSupression * fireSupressionPercentage)
                                    + (fireService * fireServicePercentage)
                                    + (buildingOrg * buildingOrgPercentage)
                                    + (passiveFire * passiveFirePercentage)
                                    + (detection * detectionPercentage)
                                    + (ignition * ignitionPercentage);

                // Create risk index for the building
                var riskIndex = await _riskIndexManager.CreateAsync(
                    siteId, buildingId,
                    (decimal)communityRiskIndex, (decimal)neighbourhoodRiskIndex, // Use the defined variables
                    (decimal)buildingRiskIndex, (decimal)buildingRiskIndexPercentage,
                    historicalFireIncident, (decimal)historicalFireIncidentPercentage,
                    (decimal)maintenance, (decimal)maintenancePercentage,
                    (decimal)fireSupression, (decimal)fireSupressionPercentage,
                    (decimal)fireService, (decimal)fireServicePercentage,
                    (decimal)buildingOrg, (decimal)buildingOrgPercentage,
                    (decimal)passiveFire, (decimal)passiveFirePercentage,
                    (decimal)detection, (decimal)detectionPercentage,
                    (decimal)ignition, (decimal)ignitionPercentage, // Pass ignitionPercentage here
                    (decimal)riskIndexScore
                );

                createdRiskIndices.Add(ObjectMapper.Map<RiskIndex, RiskIndexDto>(riskIndex));
            }

            return createdRiskIndices;
        }

        [Authorize(SiteManagementPermissions.RiskIndices.Default)]
        public  async Task<List<RiskIndexDto>> GetListBySiteAndBuildingsAsync(Guid siteId, List<Guid> buildingIds)
        {
            // Create a query to filter by siteId
            var query = await _riskIndexRepository.GetQueryableAsync();
            query = query.Where(ri => ri.SiteId == siteId);

            // Further filter by buildingIds if provided
            if (buildingIds != null && buildingIds.Any())
            {
                query = query.Where(ri => buildingIds.Contains(ri.BuildingId));
            }

            // Execute the query and retrieve the results
            var items = await AsyncExecuter.ToListAsync(query);

            // Map the results to DTOs and return
            return ObjectMapper.Map<List<RiskIndex>, List<RiskIndexDto>>(items);

        }

        #endregion
    }
}

I have done it like this: Reference Code below

  public virtual async Task<SaasTenantDto> CreateSiteTenanatAsync(SaasTenantCreateDto input)
  {
      input.ConnectionStrings = await NormalizedConnectionStringsAsync(input.ConnectionStrings);

      Tenant tenant = null;

      async Task CreateTenantAsync()
      {
          tenant = await TenantManager.CreateAsync(input.Name, input.EditionId);

          if (!input.ConnectionStrings.Default.IsNullOrWhiteSpace())
          {
              tenant.SetDefaultConnectionString(input.ConnectionStrings.Default);
          }

          if (input.ConnectionStrings.Databases != null)
          {
              foreach (var database in input.ConnectionStrings.Databases)
              {
                  tenant.SetConnectionString(database.DatabaseName, database.ConnectionString);
              }
          }

          await CheckConnectionStringAsync(tenant);

          input.MapExtraPropertiesTo(tenant);

          tenant.SetActivationState(input.ActivationState);
          if (tenant.ActivationState == TenantActivationState.ActiveWithLimitedTime)
          {
              tenant.SetActivationEndDate(input.ActivationEndDate);
          }
          /* Auto saving to ensure TenantCreatedEto handler can get the tenant! */
          await TenantRepository.InsertAsync(tenant, autoSave: true);
      }

      if (input.ConnectionStrings.Default.IsNullOrWhiteSpace() &&
          input.ConnectionStrings.Databases.IsNullOrEmpty())
      {
          /* Creating the tenant in the current UOW */
          await CreateTenantAsync();
      }
      else
      {
          /* Creating the tenant in a separate UOW to ensure it is created
           * before creating the database.
           * TODO: We should remove inner UOW once https://github.com/abpframework/abp/issues/6126 is done
           */
          using (var uow = UnitOfWorkManager.Begin(requiresNew: true))
          {
              await CreateTenantAsync();
              await uow.CompleteAsync();
          }
      }
      var adminName = "admin"; // default
      if (input.ExtraProperties.TryGetValue("adminName", out var nameObj) && nameObj is string nameStr && !string.IsNullOrWhiteSpace(nameStr))
      {
          adminName = nameStr;
      }

     
    

      await DistributedEventBus.PublishAsync(
          new TenantCreatedEto
          {
              Id = tenant.Id,
              Name = tenant.Name,
              Properties =
              {
                      {"AdminEmail", input.AdminEmailAddress},
                      {"AdminPassword", input.AdminPassword},
                 **     { "AdminName", adminName}** Added this line still not working
              }
          }
      );

      return ObjectMapper.Map<Tenant, SaasTenantDto>(tenant);
  }

We are programmatically creating directories and uploading files from another part of our application. The directories and files appear correctly in the ABP File Management module, confirming successful storage However, we are experiencing issues when trying to download these files from abp file management module.

Reference Code: private async Task<FileDescriptor> UploadFileAsync(SiteFile file, Guid directoryId) { if (file == null) throw new UserFriendlyException("Invalid file provided.");

      // Convert the byte array to a Base64 string
      string fileContentBase64 = Convert.ToBase64String(file.Content);

      byte[] fileBytes = Convert.FromBase64String(fileContentBase64);

      var fileDescriptor = new FileDescriptor(
          id: GuidGenerator.Create(),
          name: file.Name,
          mimeType: file.MimeType,
          directoryId: directoryId,
          size: fileBytes.Length,
          tenantId : _currentTenant?.Id
      );

      await _fileDescriptorRepository.InsertAsync(fileDescriptor);

      using var stream = new MemoryStream(fileBytes);
      await _blobContainer.SaveAsync(fileDescriptor.Id.ToString(), stream);

      return fileDescriptor;
  }

public class SiteFile : FullAuditedEntity<Guid> {

public Guid Id { get; set; }
public string? planType { get; set; }
public string Name { get; set; }
public string MimeType { get; set; }
public long Size { get; set; }
public byte[] Content { get; set; }

}

I want to read the time zone of the user from setting in abp. where can i get those setting or configure those setting to the user so that i can use it to convert UTC to user local time

**When I created a Tenant in the Angular UI It is creating a tenant in the saastenant table and User in AbpUser Table the Both ** When I am creating the Tenant through the swagger Post API,i It is creating a tenant in the saastenant table but not the User in AbpUser Table

To create an user and tenants do we have other api's need's to invoked

  • Exception message and full stack trace:
  • Steps to reproduce the issue:
Showing 11 to 17 of 17 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.2.0-preview. Updated on February 05, 2026, 13:24
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.