Hi,
I don't think this issue is related to ABP. You can get it in ABP as in a normal ASP.NET application. Here are a few resources you can check out:
Hi,
I downloaded and tested a new project with version 5.3.4
but could not reproduce the problem.
You can check the YourProjectNameTenantDatabaseMigrationHandler
service, and make sure it will be called when a tenant is created.
Its content should be as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.EventBus.Distributed;
using Volo.Abp.Identity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Uow;
namespace MyCompanyName.MyProjectName.Data;
public class MyProjectNameTenantDatabaseMigrationHandler :
IDistributedEventHandler<TenantCreatedEto>,
IDistributedEventHandler<TenantConnectionStringUpdatedEto>,
IDistributedEventHandler<ApplyDatabaseMigrationsEto>,
ITransientDependency
{
private readonly IEnumerable<IMyProjectNameDbSchemaMigrator> _dbSchemaMigrators;
private readonly ICurrentTenant _currentTenant;
private readonly IUnitOfWorkManager _unitOfWorkManager;
private readonly IDataSeeder _dataSeeder;
private readonly ITenantStore _tenantStore;
private readonly ILogger<MyProjectNameTenantDatabaseMigrationHandler> _logger;
public MyProjectNameTenantDatabaseMigrationHandler(
IEnumerable<IMyProjectNameDbSchemaMigrator> dbSchemaMigrators,
ICurrentTenant currentTenant,
IUnitOfWorkManager unitOfWorkManager,
IDataSeeder dataSeeder,
ITenantStore tenantStore,
ILogger<MyProjectNameTenantDatabaseMigrationHandler> logger)
{
_dbSchemaMigrators = dbSchemaMigrators;
_currentTenant = currentTenant;
_unitOfWorkManager = unitOfWorkManager;
_dataSeeder = dataSeeder;
_tenantStore = tenantStore;
_logger = logger;
}
public async Task HandleEventAsync(TenantCreatedEto eventData)
{
await MigrateAndSeedForTenantAsync(
eventData.Id,
eventData.Properties.GetOrDefault("AdminEmail") ?? MyProjectNameConsts.AdminEmailDefaultValue,
eventData.Properties.GetOrDefault("AdminPassword") ?? MyProjectNameConsts.AdminPasswordDefaultValue
);
}
public async Task HandleEventAsync(TenantConnectionStringUpdatedEto eventData)
{
if (eventData.ConnectionStringName != ConnectionStrings.DefaultConnectionStringName ||
eventData.NewValue.IsNullOrWhiteSpace())
{
return;
}
await MigrateAndSeedForTenantAsync(
eventData.Id,
MyProjectNameConsts.AdminEmailDefaultValue,
MyProjectNameConsts.AdminPasswordDefaultValue
);
/* You may want to move your data from the old database to the new database!
* It is up to you. If you don't make it, new database will be empty
* (and tenant's admin password is reset to 1q2w3E*).
*/
}
public async Task HandleEventAsync(ApplyDatabaseMigrationsEto eventData)
{
if (eventData.TenantId == null)
{
return;
}
await MigrateAndSeedForTenantAsync(
eventData.TenantId.Value,
MyProjectNameConsts.AdminEmailDefaultValue,
MyProjectNameConsts.AdminPasswordDefaultValue
);
}
private async Task MigrateAndSeedForTenantAsync(
Guid tenantId,
string adminEmail,
string adminPassword)
{
try
{
using (_currentTenant.Change(tenantId))
{
// Create database tables if needed
using (var uow = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
{
var tenantConfiguration = await _tenantStore.FindAsync(tenantId);
if (tenantConfiguration?.ConnectionStrings != null &&
!tenantConfiguration.ConnectionStrings.Default.IsNullOrWhiteSpace())
{
foreach (var migrator in _dbSchemaMigrators)
{
await migrator.MigrateAsync();
}
}
await uow.CompleteAsync();
}
// Seed data
using (var uow = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: true))
{
await _dataSeeder.SeedAsync(
new DataSeedContext(tenantId)
.WithProperty(IdentityDataSeedContributor.AdminEmailPropertyName, adminEmail)
.WithProperty(IdentityDataSeedContributor.AdminPasswordPropertyName, adminPassword)
);
await uow.CompleteAsync();
}
}
}
catch (Exception ex)
{
_logger.LogException(ex);
}
}
}
Can you provide the following information:
Hello, I will try to answer your question as clearly as possible, please let me know if there is anything unclear.
First of all, you need to read this document.
A lot of things will fall into place after reading this document, but you may need code samples.
In this case, you can often look at the abpframework/eventhub project. Since it is an open-source sample, we did not use the Volo.Payment module there, but we wrote our own module very similarly. For simplicity, this module only supports PayPal
as a gateway. For more information about the module you can check here.
Note: You don't need to write such a module because you can use the Volo.Payment
module directly. I am giving information through the EventHub
project just to give an example.
Now let's get to the usage and customization of this simple and logically almost the same module as Volo.Payment
. You can get help from the codes here.
However, as I mentioned before, the codes are similar but may not be the same, so as I said before, you should read this document first of all.
Sorry, I think I expressed myself wrongly.
Corrected version :) 👇 3-) Generate with ABP Suite the MVC template(checked public website option)
Hi 👋 , sorry for the late reply.
I tried to reproduce the problem but could not reproduce it. Here are my steps.
dotnet tool uninstall Volo.Abp.Cli -g
b. dotnet tool install -g Volo.Abp.Cli --version 6.0.1
abp suite install
command.ConfigureServices
method of the **.Web.Public
project, set the NewsletterOptions
as follows: Configure<NewsletterOptions>(options =>
{
options.AddPreference(
"Test",
new NewsletterPreferenceDefinition(
new LocalizableString(typeof(NewslatterCheckResource), "TestDisplayName"),
new LocalizableString(typeof(NewslatterCheckResource), "JoinOurTestNewsletter"),
new LocalizableString(typeof(NewslatterCheckResource), "TestPrivacyPolicyConfirmation")
)
);
})
5-) Add the NewsletterViewComponent
to a page in the **.Web.Public
project as below:
@await Component.InvokeAsync(
typeof(NewsletterViewComponent),
new
{
preference = "Test",
source = "Footer",
requestAdditionalPreferencesLater = false
})
Result:
Is there anything I missed?
If it doesn't work when you do these steps. Please let me know.
You can override EmailConfirmationLink.tpl
for email confirmation.
Full path: Volo.AbpIo.Account.Application/Volo/Abp/Account/Emailing/Templates/EmailConfirmationLink.tpl
Change PhoneConfirmationSms
localization value for phone number confirmation.
If an exception implements the IUserFriendlyException interface, then ABP does not change it's Message and Details properties and directly send it to the client.
You can use UserFriendlyException
for this. For more information, I recommend you look here.
Hi,
I believe you will find the answer you are looking for here. See: https://github.com/abpframework/abp/issues/10662#issuecomment-972765041
Hi,
See: https://support.abp.io/QA/Questions/3320/how-can-I-get-Mastering-ABP-Framework-e-book#answer-49debffe-e035-e3c0-569e-3a04b4cd54d4