Activities of "enisn"

In the latest dev branch we're using the latest 1.7.6 version of blazorise: https://github.com/abpframework/abp/blob/f671053ebd3698711e9b05675bceac8c86696efa/Directory.Packages.props#L21-L24

But it isn't shipped to you yet because of release cycles, it'll be delivered with ABP v9.2

If you wish, you can replace source code by using ABP CLI too: https://abp.io/docs/latest/cli#add-source-code

Hi,

If you build a complete custom website, I can suggest to you downloading source code of the theme and use it with local references from your application. Maybe Basic Theme may suits you better for customization purposes since it's built on top of the plain bootstrap no custom styles on it.

ABP Studio makes it in an easy way, just right click the theme module from Dependencies tree, and choose Replace with Source Code option:

If you have LeptonXTheme, right click to the LeptonX theme module.

This action will download the source code and add it to your solution. You can directly change theme layout, menu items, header, footer or whatever you wish in the theme project without overriding from your main application.

You can also implement new layouts according to your requirement by inspiring previously implemented layouts, that can make your development process much more faster

Hi,

Can you provide more information? Which search feature do you mention?

Hi,

ITextTemplateDefinitionManager is implemented here: https://github.com/abpframework/abp/blob/605482916e6f87b75d5a23a76ba2299fb72c9306/framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs#L9

And it uses IStaticTemplateDefinitionStore and IDynamicTemplateDefinitionStore.

And Dynamic one doesn't have any real implementation. The NullIDynamicTemplateDefinitionStore was resolved when injected:

https://github.com/abpframework/abp/blob/605482916e6f87b75d5a23a76ba2299fb72c9306/framework/src/Volo.Abp.TextTemplating.Core/Volo/Abp/TextTemplating/NullIDynamicTemplateDefinitionStore.cs#L9

You may implement your own DynamicTemplateDefinitionStore class by implementing IDynamicTemplateDefinitionStore interface that writes/read from a database table.

Something like that:

public class DatabaseTemplateDefinitionStore : IDynamicTemplateDefinitionStore, ITransientDependency
{
    protected IRepository<TemplateDefinitionEntity, Guid> TemplateDefinitionRepository { get; }

    public DatabaseTemplateDefinitionStore(IRepository<TemplateDefinition, Guid> templateDefinitionRepository)
    {
        TemplateDefinitionRepository = templateDefinitionRepository;
    }

    public async Task<TemplateDefinition> GetAsync(string name)
    {
        var entity = await TemplateDefinitionRepository.GetAsync(name);
        return MapToTemplateDefinitionAsync(entity); // Map to TemplateDefinition in your own way
    }

    public async Task<IReadOnlyList<TemplateDefinition>> GetAllAsync()
    {
        var list = await TemplateDefinitionRepository.GetListAsync();
        return list.Select(MapToTemplateDefinitionAsync).ToImmutableList(); // Map to TemplateDefinition in your own way
    }

    public async Task<TemplateDefinition?> GetOrNullAsync(string name)
    {
        var entity = await TemplateDefinitionRepository.FindAsync(name);

        return entity == null ? null : MapToTemplateDefinitionAsync(entity); // Map to TemplateDefinition in your own way
    }

    private TemplateDefinition MapToTemplateDefinitionAsync(TemplateDefinitionEntity entity)
    {
        // Implement your mapping logic here
        return new TemplateDefinition(entity.Name, entity.LocalizationResourceName, entity.DisplayName, entity.IsLayout, entity.Layout, entity.RenderEngine, entity.Properties);
    }
}

And create another AppService that creates it at runtime:


public class DynamicTemplateDefinitionAppService : IDynamicTemplateDefinitionStore, ITransientDependency
{
    protected IRepository<TemplateDefinitionEntity, Guid> TemplateDefinitionRepository { get; }

    public DynamicTemplateDefinitionAppService(IRepository<TemplateDefinition, Guid> templateDefinitionRepository)
    {
        TemplateDefinitionRepository = templateDefinitionRepository;
    }

    public async Task CreateAsync(TemplateDefinitionDto input)
    {
        var entity = new TemplateDefinitionEntity(input.Name, input.LocalizationResourceName, input.DisplayName, input.IsLayout, input.Layout, input.RenderEngine, input.Properties);
        await TemplateDefinitionRepository.InsertAsync(entity);
    }

    // all other CRUD methods can be implemented similarly
}

Hi,

Sorry to hear that. Updating client-proxies might be required. Can you check if your client-proxies are updated? https://abp.io/docs/latest/framework/ui/angular/service-proxies

Our @angularteam will help you better in this issue soon.

Hi,

In the Blazor, icons are coming from blazorise and it seems it's related to Blazorise.

For the official ABP v9.1 packages it seems we are dependent on Blazorise 1.6.2. https://github.com/abpframework/abp/blob/ea46c04b56a4dded54fe1fd684cc89ef4094352b/Directory.Packages.props#L20

Can you try downgrading to 1.6.2 in your application?

If you directly use DomainServices instead of using AppServices, you will bypass the permission checks, you can check how they're implemented and apply the same logic in your service, or you can use IdentityUserManager in your code by injecting it.

It extends UserManager<> from Microsoft.AspNetCore.Identity

https://github.com/abpframework/abp/blob/af1e92c5aff2d7ad9991fd46a0f2eed4bf4f559c/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserManager.cs#L74

Hi,

I need to ask some additional questions.

  1. Can you check the publisher RabbitMQ configuration is correct from the appsettings.json?

  2. Also if you have different applications, make sure you're using the exact same CustomerUpdatedEto class from 2 different projecsts.

    • Make sure depending on .Contracts package where CustomerUpdatedEto is located from subscriber project.
  3. Try adding [Serialize] attribute over CustomerUpdatedEto class

    [Serializable]
    [EventName("MyProject.CustomerService.Customers.CustomerUpdated")]
    public class CustomerUpdatedEto : EtoBase
    {
        // ...
    }
    
  4. In your example I see IDistributedEventHandler but there is no such an interface in ABP Framework. It should be IDistributedEventHandler<TEvent>, can you try using it as it is like IDistributedEventHandler<CustomerUpdatedEto>

  5. Do you see any logs in the publisher application logs whenever you publish an event? There might be an error that can help to find problem.

  6. Do you use Microservice solution or is Outbox/Inbox pattern enabled in your application?

Hi,

ABP already has a built-in system for managing 2FA through settings, which can be configured globally or per tenant:

// In Account Admin UI
await SettingManager.SetForCurrentTenantAsync(IdentityProSettingNames.TwoFactor.Behaviour, input.TwoFactorBehaviour.ToString());

We already set is per each tenant. So you can manage it through settings.

Google Authenticator is already supported built-in, you do not have to take any action: https://abp.io/docs/latest/modules/identity/two-factor-authentication#verification-providers

Just enable it and start using.

Remember, users should have a verified e-mail or phone number to activate 2FA.


As a second question, to SMS integration ABP has an infrastructure for it and has an implementation with Twilio: https://abp.io/docs/latest/modules/twilio-sms

But if you wish to use Infobip you should implment it on your own:

  • Add Volo.Abp.Sms nuget package to your project:
abp add-package Volo.Abp.Sms
  • Create InfobipSmsSender that implements ISmsSender
[Dependency(ReplaceServices = true)]
[ExposeServices(typeof(ISmsSender))]
public class InfobipSmsSender : ISmsSender, ITransientDependency
{
    private readonly IConfiguration _configuration;
    private readonly HttpClient _httpClient;

    public InfobipSmsSender(IConfiguration configuration, IHttpClientFactory httpClientFactory)
    {
        _configuration = configuration;
        _httpClient = httpClientFactory.CreateClient("Infobip");
    }

    public async Task SendAsync(SmsMessage smsMessage)
    {
        var baseUrl = _configuration["Infobip:BaseUrl"];
        var apiKey = _configuration["Infobip:ApiKey"];
        var sender = _configuration["Infobip:Sender"];

        var requestBody = new
        {
            messages = new[]
            {
                new
                {
                    from = sender,
                    destinations = new[] { new { to = smsMessage.PhoneNumber } },
                    text = smsMessage.Text
                }
            }
        };

        var request = new HttpRequestMessage(HttpMethod.Post, $"{baseUrl}/sms/2/text/advanced")
        {
            Content = new StringContent(JsonSerializer.Serialize(requestBody), Encoding.UTF8, "application/json")
        };

        request.Headers.Add("Authorization", $"App {apiKey}");

        await _httpClient.SendAsync(request);
    }
}
  • And the appsettings.json:
{
  "Infobip": {
    "BaseUrl": "https://api.infobip.com",
    "ApiKey": "your-api-key",
    "Sender": "YourApp"
  }
}

Account Pro module uses ISmsSender interface to send Security Code and Confirmation Code, so implementing this interface is enough to make it work.

Showing 1 to 10 of 678 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
Do you need assistance from an ABP expert?
Schedule a Meeting
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v9.3.0-preview. Updated on April 16, 2025, 12:13