Open Closed

openiddict add extra property, the value can not save, #3836


0
zangwanyu created
  • ABP Framework version: v6.0.0
  • UI type: Blazor
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes
  • Exception message and stack trace:
  • [12:18:25 DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:94c36bd4-906c-396b-19fa-3a06ce4ddc17,n:OpenIddictPro.Application [12:18:25 DBG] Found in the cache: pn:U,pk:94c36bd4-906c-396b-19fa-3a06ce4ddc17,n:OpenIddictPro.Application [12:18:25 DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:OpenIddictPro.Application [12:18:25 DBG] Found in the cache: pn:R,pk:admin,n:OpenIddictPro.Application [12:18:25 DBG] PermissionStore.GetCacheItemAsync: pn:C,pk:vSkysoft_BlazorServer,n:OpenIddictPro.Application [12:18:25 DBG] Found in the cache: pn:C,pk:vSkysoft_BlazorServer,n:OpenIddictPro.Application [12:18:25 INF] Executing ObjectResult, writing value of type 'Volo.Abp.OpenIddict.Applications.Dtos.ApplicationDto'. [12:18:25 INF] Executed action Volo.Abp.OpenIddict.ApplicationController.GetAsync (Volo.Abp.OpenIddict.Pro.HttpApi) in 42.6238ms [12:18:25 INF] Executed endpoint 'Volo.Abp.OpenIddict.ApplicationController.GetAsync (Volo.Abp.OpenIddict.Pro.HttpApi)' [12:18:25 INF] Request finished HTTP/1.1 GET https://localhost:44388/api/openiddict/applications/496c821d-cf08-a729-a0d7-3a06ce526930?api-version=1.0 - 0 - 200 - application/json;+charset=utf-8 47.6289ms [12:18:34 INF] Request starting HTTP/1.1 PUT https://localhost:44388/api/openiddict/applications/496c821d-cf08-a729-a0d7-3a06ce526930?api-version=1.0 application/json;+charset=utf-8 653 [12:18:34 INF] Executing endpoint 'Volo.Abp.OpenIddict.ApplicationController.UpdateAsync (Volo.Abp.OpenIddict.Pro.HttpApi)' [12:18:34 INF] Route matched with {controller = "Applications", area = "openiddictpro", action = "Update"}. Executing controller action with signature System.Threading.Tasks.Task`1[Volo.Abp.OpenIddict.Applications.Dtos.ApplicationDto] UpdateAsync(System.Guid, Volo.Abp.OpenIddict.Applications.Dtos.UpdateApplicationInput) on controller Volo.Abp.OpenIddict.ApplicationController (Volo.Abp.OpenIddict.Pro.HttpApi). [12:18:34 DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:94c36bd4-906c-396b-19fa-3a06ce4ddc17,n:OpenIddictPro.Application.Update [12:18:34 DBG] Found in the cache: pn:U,pk:94c36bd4-906c-396b-19fa-3a06ce4ddc17,n:OpenIddictPro.Application.Update [12:18:34 DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:OpenIddictPro.Application.Update [12:18:34 DBG] Found in the cache: pn:R,pk:admin,n:OpenIddictPro.Application.Update [12:18:34 DBG] PermissionStore.GetCacheItemAsync: pn:C,pk:vSkysoft_BlazorServer,n:OpenIddictPro.Application.Update [12:18:34 DBG] Found in the cache: pn:C,pk:vSkysoft_BlazorServer,n:OpenIddictPro.Application.Update [12:18:34 DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:94c36bd4-906c-396b-19fa-3a06ce4ddc17,n:OpenIddictPro.Application [12:18:34 DBG] Found in the cache: pn:U,pk:94c36bd4-906c-396b-19fa-3a06ce4ddc17,n:OpenIddictPro.Application [12:18:34 DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:OpenIddictPro.Application [12:18:34 DBG] Found in the cache: pn:R,pk:admin,n:OpenIddictPro.Application [12:18:34 DBG] PermissionStore.GetCacheItemAsync: pn:C,pk:vSkysoft_BlazorServer,n:OpenIddictPro.Application [12:18:34 DBG] Found in the cache: pn:C,pk:vSkysoft_BlazorServer,n:OpenIddictPro.Application [12:18:34 WRN] Savepoints are disabled because Multiple Active Result Sets (MARS) is enabled. If 'SaveChanges' fails, then the transaction cannot be automatically rolled back to a known clean state. Instead, the transaction should be rolled back by the application before retrying 'SaveChanges'. See https://go.microsoft.com/fwlink/?linkid=2149338 for more information. To identify the code which triggers this warning, call 'ConfigureWarnings(w => w.Throw(SqlServerEventId.SavepointsDisabledBecauseOfMARS))'. [12:18:34 DBG] Added 0 entity changes to the current audit log [12:18:34 DBG] Added 0 entity changes to the current audit log [12:18:34 INF] Executing ObjectResult, writing value of type 'Volo.Abp.OpenIddict.Applications.Dtos.ApplicationDto'. [12:18:34 INF] Executed action Volo.Abp.OpenIddict.ApplicationController.UpdateAsync (Volo.Abp.OpenIddict.Pro.HttpApi) in 402.5191ms [12:18:34 INF] Executed endpoint 'Volo.Abp.OpenIddict.ApplicationController.UpdateAsync (Volo.Abp.OpenIddict.Pro.HttpApi)' [12:18:34 DBG] Added 0 entity changes to the current audit log [12:18:34 DBG] Added 0 entity changes to the current audit log [12:18:34 DBG] Added 0 entity changes to the current audit log [12:18:34 DBG] Added 0 entity changes to the current audit log [12:18:34 INF] Request finished HTTP/1.1 PUT https://localhost:44388/api/openiddict/applications/496c821d-cf08-a729-a0d7-3a06ce526930?api-version=1.0 application/json;+charset=utf-8 653 - 200 - application/json;+charset=utf-8 670.3044ms
  • Steps to reproduce the issue:"

8 Answer(s)
  • 0
    maliming created
    Support Team

    hi

    Please share the full steps to reproduce. Thanks.

  • 0
    zangwanyu created

    @using Volo.Abp.OpenIddict.Pro.Blazor.Pages

    @inherits ApplicationManagement

    @{ base.BuildRenderTree(__builder); }

    @if (HasUpdatePermission){

    <DxPopup HeaderText="@L["Application"]" @bind-Visible="ApplicationPopup" Context="DxPopupContext" @ref="dxPopup"> <BodyContentTemplate>

        &lt;DxFormLayout&gt;
            
            &lt;DxFormLayoutItem ColSpanMd=&quot;12&quot; Context=&quot;item&quot;&gt;
                &lt;DxComboBox Data=&quot;organizationUnitDtoList&quot;
                            FilteringMode=&quot;DataGridFilteringMode.Contains&quot;
                            TextFieldName=&quot;DisplayName&quot;
                            ValueFieldName=&quot;Id&quot;
                            ClearButtonDisplayMode=&quot;DataEditorClearButtonDisplayMode.Auto&quot;
                            @bind-Value=&quot;@(EditingEntity.ExtraProperties[&quot;OrganizationUnitId&quot;])&quot;&gt;
                    @L["OrganizationUnit"]
                &lt;/DxComboBox&gt;
            &lt;/DxFormLayoutItem&gt;
                        
            &lt;DxFormLayoutItem ColSpanMd=&quot;12&quot; Context=&quot;item&quot;&gt;
                &lt;DxCheckBox @bind-Checked=&quot;@(NeedVAuthority)&quot;&gt;
                    @L["NeedVAuthority"]
                &lt;/DxCheckBox&gt;
            &lt;/DxFormLayoutItem&gt;
    
            &lt;DxFormLayoutItem ColSpanMd=&quot;12&quot;&gt;
                &lt;div class=&quot;right-align&quot;&gt;
                    &lt;DxButton RenderStyle=&quot;ButtonRenderStyle.Primary&quot; Text=&quot;@L[&quot;Cancel&quot;]&quot; Click=&quot;()=&gt;ApplicationPopup=false" />
    

    <DxButton RenderStyle="ButtonRenderStyle.Secondary" Text="@L["Confirm"]" Click="ConfirmChange" />

                &lt;/div&gt;
            &lt;/DxFormLayoutItem&gt;
    
        &lt;/DxFormLayout&gt;
    
    &lt;/BodyContentTemplate&gt;
    

    </DxPopup> }

    using DevExpress.Blazor; using Microsoft.AspNetCore.Components; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading.Tasks; using Volo.Abp.AspNetCore.Components.Web.Extensibility.EntityActions; using Volo.Abp.BlazoriseUI; using Volo.Abp.DependencyInjection; using Volo.Abp.Identity; using Volo.Abp.ObjectExtending; using Volo.Abp.ObjectMapping; using Volo.Abp.OpenIddict.Applications; using Volo.Abp.OpenIddict.Applications.Dtos; using Volo.Abp.OpenIddict.Pro.Blazor.Pages;

    namespace aa.IdentityService.Blazor.Pages.IdentityServer {

    [ExposeServices(typeof(ApplicationManagement))]

    [Dependency(ReplaceServices = true)]

    public partial class CustomApplicationManagement
    {
        [Inject] IOrganizationUnitAppService OrganizationUnitAppService { get; set; }
    
        bool ApplicationPopup;
        DxPopup dxPopup;
    
        List&lt;OrganizationUnitWithDetailsDto&gt; organizationUnitDtoList;
    
        protected override async Task OnInitializedAsync()
        {
            await base.OnInitializedAsync();
            var organizationUnitResult = await OrganizationUnitAppService.GetListAllAsync();
            organizationUnitDtoList = organizationUnitResult.Items.Where(u => u.ParentId == null).ToList();
        }
    
        protected async override Task OpenCreateModalAsync()
        {
            Scopes = (await ScopeAppService.GetAllScopesAsync()).ToDictionary(x => x.Name, x => false);
            CreateInput = new ApplicationModalView();
            CreateInput.ExtraProperties["NeedVAuthority"] = false;
            try
            {
                if (CreateValidationsRef != null)
                {
                    await CreateValidationsRef.ClearAll();
                }
    
                await CheckCreatePolicyAsync();
    
                NewEntity = new CreateApplicationInput();
    
                // Mapper will not notify Blazor that binded values are changed
                // so we need to notify it manually by calling StateHasChanged
                await InvokeAsync(async () =>
                {
                    StateHasChanged();
                    if (CreateModal != null)
                    {
                        await CreateModal.Show();
                    }
    
                });
            }
            catch (Exception ex)
            {
                await HandleErrorAsync(ex);
            }
        }
    
    
        async Task OpenApplicationAsync(ApplicationDto entity)
        {
            if (dxPopup is not null)
            {
                ApplicationPopup = true;
    
                var entityDto = await AppService.GetAsync(entity.Id);
    
                EditingEntityId = entity.Id;
                EditingEntity = MapToEditingEntity(entityDto);
                EditingEntity.ExtraProperties["NeedVAuthority"] = false;
                EditingEntity.ExtraProperties["OrganizationUnitId"] = "";
    
                //EditingClientModelView = ObjectMapper.Map&lt;UpdateClientDto, UpdateClientModelView&gt;(EditingEntity);
                await InvokeAsync(StateHasChanged);
    
                await dxPopup.ShowAsync();
            }
        }
    
    
    
        protected async override Task OpenEditModalAsync(ApplicationDto entity)
        {
            await base.OpenEditModalAsync(entity);
            CreateInput.ClientUri = entity.ClientUri;
            CreateInput.LogoUri = entity.LogoUri;
            Scopes = (await ScopeAppService.GetAllScopesAsync()).ToDictionary(x => x.Name, x => EditingEntity.Scopes.Any(s => s == x.Name));
            await InvokeAsync(StateHasChanged);
        }
    
        protected override UpdateApplicationInput MapToEditingEntity(ApplicationDto entityDto)
        {
            UpdateInput = ObjectMapper.Map&lt;ApplicationDto, ApplicationModalView&gt;(entityDto);
            return base.MapToEditingEntity(entityDto); ;
        }
    
        protected override Task OnUpdatingEntityAsync()
        {
            UpdateInput.Scopes = Scopes.Where(x => x.Value).Select(x => x.Key).ToHashSet();
            UpdateInput.LogoUri = CreateInput.LogoUri;
            UpdateInput.ClientUri = CreateInput.ClientUri;
            EditingEntity = ObjectMapper.Map&lt;ApplicationModalView, UpdateApplicationInput&gt;(UpdateInput);
            return base.OnUpdatingEntityAsync();
        }
    
        protected override ValueTask SetEntityActionsAsync()
        {
            EntityActions
                .Get&lt;ApplicationManagement&gt;()
                .Add(
                    new EntityAction
                    {
                        Text = L["Application"],
                        Visible = (data) => HasUpdatePermission,
                        Clicked = async (data) => await OpenApplicationAsync(data.As&lt;ApplicationDto&gt;())
                    });
    
            return base.SetEntityActionsAsync();
        }
    
        bool NeedVAuthority
        {
            get => (bool)EditingEntity.ExtraProperties["NeedVAuthority"];
            set => EditingEntity.ExtraProperties["NeedVAuthority"] = value;
        }
    

    async Task ConfirmChange()

    {

    await AppService.UpdateAsync(EditingEntityId, EditingEntity);

    ApplicationPopup = false;

    }

    }
    

    }

    Invoke method ConfirmChange()

  • 0
    maliming created
    Support Team

    Please try to format your code. It is unreadable. Thanks

  • 0
    zangwanyu created

    CustomApplicationManagment.razor

    @using Volo.Abp.OpenIddict.Pro.Blazor.Pages @inherits ApplicationManagement

    @{ base.BuildRenderTree(__builder); }

    @if (HasUpdatePermission){

    <DxPopup HeaderText="@L["Application"]" @bind-Visible="ApplicationPopup" Context="DxPopupContext" @ref="dxPopup"> <BodyContentTemplate>

        &lt;DxFormLayout&gt;
            
            &lt;DxFormLayoutItem ColSpanMd=&quot;12&quot; Context=&quot;item&quot;&gt;
                &lt;DxComboBox Data=&quot;organizationUnitDtoList&quot;
                            FilteringMode=&quot;DataGridFilteringMode.Contains&quot;
                            TextFieldName=&quot;DisplayName&quot;
                            ValueFieldName=&quot;Id&quot;
                            ClearButtonDisplayMode=&quot;DataEditorClearButtonDisplayMode.Auto&quot;
                            @bind-Value=&quot;@(EditingEntity.ExtraProperties[&quot;OrganizationUnitId&quot;])&quot;&gt;
                    @L["OrganizationUnit"]
                &lt;/DxComboBox&gt;
            &lt;/DxFormLayoutItem&gt;
                        
            &lt;DxFormLayoutItem ColSpanMd=&quot;12&quot; Context=&quot;item&quot;&gt;
                &lt;DxCheckBox @bind-Checked=&quot;@(NeedVAuthority)&quot;&gt;
                    @L["NeedVAuthority"]
                &lt;/DxCheckBox&gt;
            &lt;/DxFormLayoutItem&gt;
    
            &lt;DxFormLayoutItem ColSpanMd=&quot;12&quot;&gt;
                &lt;div class=&quot;right-align&quot;&gt;
                    &lt;DxButton RenderStyle=&quot;ButtonRenderStyle.Primary&quot; Text=&quot;@L[&quot;Cancel&quot;]&quot; Click=&quot;()=&gt;ApplicationPopup=false" />
                    &lt;DxButton RenderStyle=&quot;ButtonRenderStyle.Secondary&quot; Text=&quot;@L[&quot;Confirm&quot;]&quot; Click=&quot;ConfirmChange&quot; /&gt;
                &lt;/div&gt;
            &lt;/DxFormLayoutItem&gt;
    
        &lt;/DxFormLayout&gt;
    
    &lt;/BodyContentTemplate&gt;
    

    </DxPopup> }

    CustomApplicationManagement.razor.cs

    using DevExpress.Blazor;
    using Microsoft.AspNetCore.Components;
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using System.Linq;
    using System.Threading.Tasks;
    using Volo.Abp.AspNetCore.Components.Web.Extensibility.EntityActions;
    using Volo.Abp.BlazoriseUI;
    using Volo.Abp.DependencyInjection;
    using Volo.Abp.Identity;
    using Volo.Abp.ObjectExtending;
    using Volo.Abp.ObjectMapping;
    using Volo.Abp.OpenIddict.Applications;
    using Volo.Abp.OpenIddict.Applications.Dtos;
    using Volo.Abp.OpenIddict.Pro.Blazor.Pages;
    
    namespace MySoft.IdentityService.Blazor.Pages.IdentityServer
    {
    
    [ExposeServices(typeof(ApplicationManagement))]
    [Dependency(ReplaceServices = true)]
    public partial class CustomApplicationManagement
    {
        [Inject] IOrganizationUnitAppService OrganizationUnitAppService { get; set; }
    
        bool ApplicationPopup;
        DxPopup dxPopup;
    
        List<OrganizationUnitWithDetailsDto> organizationUnitDtoList;
    
        protected override async Task OnInitializedAsync()
        {
            await base.OnInitializedAsync();
            var organizationUnitResult = await OrganizationUnitAppService.GetListAllAsync();
            organizationUnitDtoList = organizationUnitResult.Items.Where(u => u.ParentId == null).ToList();
        }
    
        protected async override Task OpenCreateModalAsync()
        {
            Scopes = (await ScopeAppService.GetAllScopesAsync()).ToDictionary(x => x.Name, x => false);
            CreateInput = new ApplicationModalView();
            CreateInput.ExtraProperties["NeedVAuthority"] = false;
            try
            {
                if (CreateValidationsRef != null)
                {
                    await CreateValidationsRef.ClearAll();
                }
    
                await CheckCreatePolicyAsync();
    
                NewEntity = new CreateApplicationInput();
    
                // Mapper will not notify Blazor that binded values are changed
                // so we need to notify it manually by calling StateHasChanged
                await InvokeAsync(async () =>
                {
                    StateHasChanged();
                    if (CreateModal != null)
                    {
                        await CreateModal.Show();
                    }
    
                });
            }
            catch (Exception ex)
            {
                await HandleErrorAsync(ex);
            }
        }
    
    
        async Task OpenApplicationAsync(ApplicationDto entity)
        {
            if (dxPopup is not null)
            {
                ApplicationPopup = true;
    
                var entityDto = await AppService.GetAsync(entity.Id);
    
                EditingEntityId = entity.Id;
                EditingEntity = MapToEditingEntity(entityDto);
                EditingEntity.ExtraProperties["NeedVAuthority"] = false;
                EditingEntity.ExtraProperties["OrganizationUnitId"] = "";
    
                //EditingClientModelView = ObjectMapper.Map<UpdateClientDto, UpdateClientModelView>(EditingEntity);
                await InvokeAsync(StateHasChanged);
    
                await dxPopup.ShowAsync();
            }
        }
    
    
    
        protected async override Task OpenEditModalAsync(ApplicationDto entity)
        {
            await base.OpenEditModalAsync(entity);
            CreateInput.ClientUri = entity.ClientUri;
            CreateInput.LogoUri = entity.LogoUri;
            Scopes = (await ScopeAppService.GetAllScopesAsync()).ToDictionary(x => x.Name, x => EditingEntity.Scopes.Any(s => s == x.Name));
            await InvokeAsync(StateHasChanged);
        }
    
        protected override UpdateApplicationInput MapToEditingEntity(ApplicationDto entityDto)
        {
            UpdateInput = ObjectMapper.Map<ApplicationDto, ApplicationModalView>(entityDto);
            return base.MapToEditingEntity(entityDto); ;
        }
    
        protected override Task OnUpdatingEntityAsync()
        {
            UpdateInput.Scopes = Scopes.Where(x => x.Value).Select(x => x.Key).ToHashSet();
            UpdateInput.LogoUri = CreateInput.LogoUri;
            UpdateInput.ClientUri = CreateInput.ClientUri;
            EditingEntity = ObjectMapper.Map<ApplicationModalView, UpdateApplicationInput>(UpdateInput);
            return base.OnUpdatingEntityAsync();
        }
    
        protected override ValueTask SetEntityActionsAsync()
        {
            EntityActions
                .Get<ApplicationManagement>()
                .Add(
                    new EntityAction
                    {
                        Text = L["Application"],
                        Visible = (data) => HasUpdatePermission,
                        Clicked = async (data) => await OpenApplicationAsync(data.As<ApplicationDto>())
                    });
    
            return base.SetEntityActionsAsync();
        }
    
        bool NeedVAuthority
        {
            get => (bool)EditingEntity.ExtraProperties["NeedVAuthority"];
            set => EditingEntity.ExtraProperties["NeedVAuthority"] = value;
        }
        async Task ConfirmChange()
        {
            await AppService.UpdateAsync(EditingEntityId, EditingEntity);
            ApplicationPopup = false;
        }
      }
    }
    

    the AppService.UpdateAsync method can't save extra properties values

    var entityDto = await AppService.GetAsync(entity.Id); The GetAsync method also can't get extra properties values

  • 0
    maliming created
    Support Team

    ok, I will check this asap.

  • 0
    maliming created
    Support Team

    hi

    Can you create a new template project and reproduce the problem? (You can call application in unit test)

  • 0
    zangwanyu created

    yes

    using Volo.Abp.ObjectExtending;
    using Volo.Abp.Threading;
    
    namespace TestApp;
    
    public static class TestAppModuleExtensionConfigurator
    {
        private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
    
        public static void Configure()
        {
            OneTimeRunner.Run(() =>
            {
                ConfigureExistingProperties();
                ConfigureExtraProperties();
            });
        }
    
        private static void ConfigureExistingProperties()
        {
            /* You can change max lengths for properties of the
             * entities defined in the modules used by your application.
             *
             * Example: Change user and role name max lengths
    
               IdentityUserConsts.MaxNameLength = 99;
               IdentityRoleConsts.MaxNameLength = 99;
    
             * Notice: It is not suggested to change property lengths
             * unless you really need it. Go with the standard values wherever possible.
             *
             * If you are using EF Core, you will need to run the add-migration command after your changes.
             */
        }
    
        private static void ConfigureExtraProperties()
        {
            /* You can configure extra properties for the
             * entities defined in the modules used by your application.
             *
             * This class can be used to define these extra properties
             * with a high level, easy to use API.
             *
             * Example: Add a new property to the user entity of the identity module
    
               ObjectExtensionManager.Instance.Modules()
                  .ConfigureIdentity(identity =>
                  {
                      identity.ConfigureUser(user =>
                      {
                          user.AddOrUpdateProperty<string>( //property type: string
                              "SocialSecurityNumber", //property name
                              property =>
                              {
                                  //validation rules
                                  property.Attributes.Add(new RequiredAttribute());
                                  property.Attributes.Add(new StringLengthAttribute(64) {MinimumLength = 4});
    
                                  //...other configurations for this property
                              }
                          );
                      });
                  });
    
             * See the documentation for more:
             * https://docs.abp.io/en/abp/latest/Module-Entity-Extensions
             */
    
            ObjectExtensionManager.Instance.Modules()
                  .ConfigureOpenIddict(openid =>
                  {
                      openid.ConfigureApplication(app =>
                      {
                          app.AddOrUpdateProperty<string>("Description");                        
                      });
                  });
        }
    }
    
    
    using Volo.Abp.ObjectExtending;
    using Volo.Abp.OpenIddict.Applications;
    using Volo.Abp.Threading;
    
    namespace TestApp.EntityFrameworkCore;
    
    public static class TestAppEfCoreEntityExtensionMappings
    {
        private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();
    
        public static void Configure()
        {
            TestAppGlobalFeatureConfigurator.Configure();
            TestAppModuleExtensionConfigurator.Configure();
    
            OneTimeRunner.Run(() =>
            {
                /* You can configure extra properties for the
                 * entities defined in the modules used by your application.
                 *
                 * This class can be used to map these extra properties to table fields in the database.
                 *
                 * USE THIS CLASS ONLY TO CONFIGURE EF CORE RELATED MAPPING.
                 * USE TestAppModuleExtensionConfigurator CLASS (in the Domain.Shared project)
                 * FOR A HIGH LEVEL API TO DEFINE EXTRA PROPERTIES TO ENTITIES OF THE USED MODULES
                 *
                 * Example: Map a property to a table field:
    
                     ObjectExtensionManager.Instance
                         .MapEfCoreProperty<IdentityUser, string>(
                             "MyProperty",
                             (entityBuilder, propertyBuilder) =>
                             {
                                 propertyBuilder.HasMaxLength(128);
                             }
                         );
    
                 * See the documentation for more:
                 * https://docs.abp.io/en/abp/latest/Customizing-Application-Modules-Extending-Entities
                 */
    
                ObjectExtensionManager.Instance
                    .MapEfCoreProperty<OpenIddictApplication, string>("Description");
            });
        }
    }
    
    

    The test case code is as follows

    using Shouldly;
    using System.Threading.Tasks;
    using Volo.Abp.OpenIddict.Applications;
    using Volo.Abp.OpenIddict.Applications.Dtos;
    using Xunit;
    
    namespace TestApp.Samples;
    
    /* This is just an example test class.
     * Normally, you don't test code of the modules you are using
     * (like IIdentityUserAppService here).
     * Only test your own application services.
     */
    public class SampleAppServiceTests : TestAppApplicationTestBase
    {
        private readonly IApplicationAppService _applicationAppService;
    
        public SampleAppServiceTests()
        {
            _applicationAppService = GetRequiredService<IApplicationAppService>();
        }
    
        [Fact]
        public async Task Should_Set_Description_Of_An_Application()
        {
            await WithUnitOfWorkAsync(async () =>
            {
                var app = new CreateApplicationInput()
                {
                    ClientId = "test",
                    DisplayName = "test"
                };
    
                app.ExtraProperties["Description"] = "Description1";
    
                await _applicationAppService.CreateAsync(app);
            });
            var list = await _applicationAppService.GetListAsync(new()
            {
                MaxResultCount = 1
            });
    
            // list.Items[0].ExtraProperties["Description"].ShouldBe("Description1");
    
            var app = await _applicationAppService.GetAsync(list.Items[0].Id);
    
            app.ExtraProperties["Description"].ShouldBe("Description1");
    
            
        }
    }
    
    

    The test failed as follows

     TestApp.Samples.SampleAppServiceTests.Should_Set_Description_Of_An_Application
       源: SampleAppServiceTests.cs 行 33
       持续时间: 4.3 秒
    
      消息: 
    Shouldly.ShouldAssertException : app.ExtraProperties["Description"]
        should be
    "Description1"
        but was
    null
    
      堆栈跟踪: 
    SampleAppServiceTests.Should_Set_Description_Of_An_Application() 行 56
    ExceptionDispatchInfo.Throw()
    TaskAwaiter.ThrowForNonSuccess(Task task)
    TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    TaskAwaiter.GetResult()
    --- End of stack trace from previous location ---
    ExceptionDispatchInfo.Throw()
    TaskAwaiter.ThrowForNonSuccess(Task task)
    TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    TaskAwaiter.GetResult()
    ExceptionDispatchInfo.Throw()
    TaskAwaiter.ThrowForNonSuccess(Task task)
    TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
    TaskAwaiter.GetResult()
    
    

  • 0
    maliming created
    Support Team

    hi

    This is an unknown problem, We will release a new 6.0 patch version.

    https://github.com/abpframework/abp/pull/14306