Hi, EngincanV I did build. See my Step 4. Graph build. OK I can not add new Entity to [DemoSolution2] using ABP Suite. After adding it gives me error and I can not build using graph due to errors in module. So you did not answer my quition: why my module [NewModule] is impacted if I am adding entity into [DemoSolution2]?
I will share solution soon.
Thanks. I got your email, and will check the problem.
Hi, your finding that removing await allows the event to be published immediately when onUnitOfWorkComplete is false seems to be the correct workaround. Because, since you are not using the await keyword, it works like a sync method. But just notice, when you do that in an unhandled exception occurs then you are on your own in exception handling.
Second issue, after event published, even event handler method is virtual still it is not working correctly without using _unitOfWorkManager as below. Without using _unitOfWorkManager, child entities is not commiting to the db.
By using _unitOfWorkManager.Begin(requiresNew: true, isTransactional: true), you are explicitly creating a new and independent unit of work for the duration of your event handler's execution. This ensures that all operations within this using block, including changes to child entities, are tracked by EF Core within this specific unit of work.
Actually, since you are using the [UnitOfWork] attribute, normally it should work seamlessly but it's possible that the event handler is being invoked in a context where the ambient unit of work has already been completed or disposed, or perhaps the event handling mechanism in this specific scenario doesn't correctly hook into the ambient unit of work management for child entities. I'll check this.
Regards.
Hi, in the GetWaitingEventsAsync method, a new optional parameter was added, and your problem seems to related to package version inconsistency. I know you've already cleaned your solution, rebuilt it, and checked the .dll files, but it looks like one of your .csproj files may have an incorrect package version.
Could you please check your .csproj files and confirm that all package versions are correct?
Hi, thanks for the detailed information. Your code for extending the IdentityUser with a DateOnly property for BirthDate looks correct at first glance. ABP's entity extension mechanism should handle this. However, the fact that the property always defaults to 0001-01-01 suggests that the value is indeed not being set during user creation.
Your suspicion about type casting is likely on the right track. You can try to explicitly configure column type in mapping as follows:
ObjectExtensionManager.Instance.MapEfCoreProperty<IdentityUser, DateOnly>(
UserExtraPropertyNames.BirthDate,
(_, propertyBuilder) =>
{
propertyBuilder.IsRequired();
propertyBuilder.HasColumnType("date");
});
By explicitly setting the column type (propertyBuilder.HasColumnType("date")), I think your problem should be resolved. Can you try it and let me know if it fixes, please?
Hi, it seems in your App.razor file (under Components folder), you should set base as follows (update the related base tag's href):
<base href="/Session/Onboarding/" />
The <base> HTML element specifies the base URL to use for all relative URLs in a document. There can be only one <base> element in a document. Ref: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
Thanks for the answer! We are aiming to enable Microsoft Entra Id SSO login for some of our customers, that use our (Abp) application. How is that going to work when we cannot configure the azure tenant in the tenant's external login provider configuration? If only the client id and the secret are configurable, how can the customer point the configuration to their Microsoft Entra Id?
You're right to point out that simply configuring Client ID and Secret might not be enough for Microsoft Entra ID (now known as Microsoft Entra ID, formerly Azure AD) in a multi-tenant scenario. Each customer using their own Microsoft Entra ID will indeed have a unique Tenant ID (also known as Directory ID) that your application needs to target for authentication.
For that purpose, you should implement dynamic configuration using ICoonfigureOptions<>. Here is what you can do:
IConfigureOptions<OpenIdConnectOptions> for Azure AD:Since Microsoft Entra ID uses the OpenID Connect protocol, you'll need to implement
IConfigureOptions<OpenIdConnectOptions>.
public class AzureAdTenantOptionsProvider : IConfigureOptions<OpenIdConnectOptions>, ITransientDependency
{
private readonly ICurrentTenant _currentTenant;
private readonly ITenantAzureAdSettingsService _tenantAzureAdSettingsService; //NOTE: you need to implement this service
public AzureAdTenantOptionsProvider(ICurrentTenant currentTenant, ITenantAzureAdSettingsService tenantAzureAdSettingsService)
{
_currentTenant = currentTenant;
_tenantAzureAdSettingsService = tenantAzureAdSettingsService;
}
public void Configure(OpenIdConnectOptions options)
{
if (_currentTenant.Id.HasValue)
{
var tenantId = _currentTenant.Id.Value;
var azureAdSettings = _tenantAzureAdSettingsService.GetAzureAdSettings(tenantId); // Implement this
if (azureAdSettings != null && azureAdSettings.IsEnabled)
{
options.ClientId = azureAdSettings.ClientId;
options.ClientSecret = azureAdSettings.ClientSecret;
options.Authority = $"https://login.microsoftonline.com/{azureAdSettings.TenantId}/v2.0";
options.ResponseType = "code"; // Or your preferred response type
options.SaveTokens = true;
options.GetClaimsFromUserInfoEndpoint = true;
// Add other necessary options as per your requirements
}
else
{
// Or configure default behavior
}
}
else
{
// Configure default Azure AD settings for the host if needed
}
}
}
ConfigureServices method):services.ConfigureOptions<AzureAdTenantOptionsProvider>();
Note that, this requires additional implementation on your side and in the above example, I have just tried to provide you an approach. Since this is not fully related to ABP, you may need to check additional articles on the web.
In summary, to enable Microsoft Entra ID SSO login for different tenants:
Regards.
Hi, I'm unable to reproduce your problem. Tried applying each step you provided but could not reproduce it. Your problems seem to be related to that you have not built your solution.
Please get a graphBuild on your solution (dotnet build /graphbuild) and see if really there is any build error. If still there are build errors, share your solution via email (to support@abp.io with ticket number), so I can check your solution. Since, could not produce the problem with the specified steps, I'm unable to help you at that point and waiting for your confirmation.
Regards.
Hi, yes you can generate CRUD pages via ABP CLI, please refer to the Generating CRUD Pages via Command Line section in the ABP Suite documentation.
Let me know, if you need further info. Regards.
I saw that reference but it assumes a json metadata file was generated via the Suite tool initially. If one is to manually replicate this, what are the minimum required properties?
You can use the following json template as an example:
Promotion.json (entity name: "Promotion", and only has a single property named "Title")
{
"Id": "1148f4fe-8dfd-4435-8953-99db98b0c82a",
"Name": "Promotion",
"OriginalName": "Promotion",
"NamePlural": "Promotions",
"DatabaseTableName": "Promotions",
"Namespace": "Promotions",
"Type": 1,
"MasterEntityName": null,
"MasterEntity": null,
"BaseClass": "FullAuditedAggregateRoot",
"PageTitle": "Promotions",
"MenuIcon": "file-alt",
"PrimaryKeyType": "Guid",
"PreserveCustomCode": true,
"IsMultiTenant": false,
"CheckConcurrency": true,
"BulkDeleteEnabled": true,
"ShouldCreateUserInterface": true,
"ShouldCreateBackend": true,
"ShouldExportExcel": true,
"ShouldAddMigration": true,
"ShouldUpdateDatabase": true,
"CreateTests": true,
"Properties": [
{
"Id": "e7c6fe43-3e99-495c-bde8-ecbbcd6793e3",
"Name": "Title",
"Type": "string",
"EnumType": "",
"EnumNamespace": "",
"EnumAngularImport": "shared/enums",
"EnumFilePath": null,
"DefaultValue": null,
"IsNullable": false,
"IsRequired": false,
"IsFilterable": true,
"AllowEmptyStrings": false,
"IsTextArea": false,
"MinLength": null,
"MaxLength": null,
"SortOrder": 0,
"SortType": 0,
"Regex": "",
"EmailValidation": false,
"ShowOnList": true,
"ShowOnCreateModal": true,
"ShowOnEditModal": true,
"ReadonlyOnEditModal": false,
"EnumValues": null,
"IsSelected": true,
"MaxFileSize": null,
"OrdinalIndex": 0
}
],
"NavigationProperties": [],
"NavigationConnections": [],
"ChildEntities": [],
"PhysicalFileName": "Promotion.json"
}
I have re-generated openiddict.pfx and made some adjustments according to the documentation, but the original problem still occurs. I would like to remind you that: a. It was able to run normally in v9.0.4; the problem occurred after upgrading to v9.1.0. b. The error event mentioned occurred during module Volo.Abp.OpenIddict.AbpOpenIddictDomainModule (Volo.Abp.OpenIddict.Domain, Version=9.0.4.0); but I searched the entire project code and could not find any content related to using Volo.Abp.OpenIddict.Domain !
Hi, thanks for the detailed information. The HTTP Error 500.30 and the subsequent System.MissingMethodException clearly indicate an issue with the OpenIddict library after the upgrade from 9.0.4 to 9.1.0.
The error message "Method not found: 'System.Collections.Generic.IAsyncEnumerable`1<System.Object> OpenIddict.Abstractions.IOpenIddictAuthorizationManager.FindAsync(System.String, System.String, System.Threading.CancellationToken)'" suggests that the Volo.Abp.OpenIddict.Domain module (version 9.0.4) is looking for a method in the OpenIddict.Abstractions library that is either no longer present or has a different signature in the version that is now being used (likely the one compatible with ABP 9.1.0).
There might be several reasons for these problems:
Ok I will try to do it on an empty template I couldn’t find the time yet can you give little bit more time and keep this open.
Sure, I'll reopen the question if our support bot closes it automatically. I'll keep the question open.