Open Closed

New module: Forms #1168


User avatar
0
Dicky.tech@gmail.com created
  • ABP Framework version: v4.3.R2
  • UI type: MVC
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): no
  • Exception message and stack trace:
  • Steps to reproduce the issue:

Have created a new app and i don't seem to see the new module: forms as per pre release notes.

How can i review it ?


14 Answer(s)
  • User Avatar
    0
    Dicky.tech@gmail.com created

    Seen it. One has to add the package.

  • User Avatar
    0
    Dicky.tech@gmail.com created

    Am using ABP 5.2.1 - MVC

    I have the below error when adding choice-based questions. The choices don't save to DB

    [19:22:29 ERR] An error occurred while saving the entity changes. See the inner exception for details.
    Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while saving the entity changes. See the inner exception for details.
     ---> Microsoft.Data.SqlClient.SqlException (0x80131904): The DELETE statement conflicted with the REFERENCE constraint "FK_FrmChoices_FrmQuestions_ChoosableQuestionId". The conflict occurred in database "SELFSERVICE", table "dbo.FrmChoices", column 'ChoosableQuestionId'.
    The statement has been terminated.
       at Microsoft.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__188_0(Task`1 result)
       at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
    --- End of stack trace from previous location ---
       at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
    --- End of stack trace from previous location ---
       at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
    ClientConnectionId:a846ae0b-c8a1-47df-b8c2-a9a86c85e45a
    Error Number:547,State:0,Class:16
       --- End of inner exception stack trace ---
       at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(StateManager stateManager, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
       at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
       at Volo.Abp.EntityFrameworkCore.AbpDbContext`1.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
       at Volo.Abp.Domain.Repositories.EntityFrameworkCore.EfCoreRepository`2.DeleteAsync(TEntity entity, Boolean autoSave, CancellationToken cancellationToken)
       at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous(IInvocation invocation, IInvocationProceedInfo proceedInfo)
       at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapter.ProceedAsync()
       at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
       at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
       at Volo.Abp.Domain.Repositories.RepositoryExtensions.HardDeleteWithUnitOfWorkAsync[TEntity](IBasicRepository`1 repository, TEntity entity, Boolean autoSave, CancellationToken cancellationToken, IUnitOfWork currentUow)
       at Volo.Abp.Domain.Repositories.RepositoryExtensions.HardDeleteAsync[TEntity](IBasicRepository`1 repository, TEntity entity, Boolean autoSave, CancellationToken cancellationToken)
       at Volo.Forms.Questions.QuestionManager.UpdateAsync(Guid id, String title, Int32 index, Boolean isRequired, String description, QuestionTypes questionType, Boolean hasOtherOption, List`1 choiceList)
       at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
       at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
       at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
       at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
       at Volo.Forms.Questions.QuestionAppService.UpdateAsync(Guid id, UpdateQuestionDto input)
       at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
       at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
       at Volo.Abp.GlobalFeatures.GlobalFeatureInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
       at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
       at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
       at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
       at Volo.Abp.Auditing.AuditingInterceptor.ProceedByLoggingAsync(IAbpMethodInvocation invocation, IAuditingHelper auditingHelper, IAuditLogScope auditLogScope)
       at Volo.Abp.Auditing.AuditingInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
       at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
       at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
       at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
       at Volo.Abp.Features.FeatureInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
       at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
       at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
       at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
       at Volo.Abp.Validation.ValidationInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
       at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
       at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
       at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue`1.ProceedAsync()
       at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation)
       at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter`1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
       at lambda_method5045(Closure , Object )
       at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.&lt;InvokeActionMethodAsync&gt;g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
       at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
    [19:22:29 INF] Executing ObjectResult, writing value of type 'Volo.Abp.Http.RemoteServiceErrorResponse'.
    [19:22:29 INF] Executed action Volo.Forms.Questions.QuestionController.UpdateAsync (Volo.Forms.HttpApi) in 458.7157ms
    [19:22:29 INF] Executed endpoint 'Volo.Forms.Questions.QuestionController.UpdateAsync (Volo.Forms.HttpApi)'
    [19:22:29 DBG] Added 0 entity changes to the current audit log
    [19:22:29 DBG] Added 0 entity changes to the current audit log
    [19:22:29 INF] Request finished HTTP/2 PUT https://localhost:44345/api/questions/807e2c84-9744-1095-d926-3a03d0665c52 application/json 485 - 500 - application/json;+charset=utf-8 706.6463ms
    [19:22:29 INF] Request starting HTTP/2 GET https://localhost:44345/images/logo/logo-dark.png - -
    [19:22:29 INF] Sending file. Request path: '/images/logo/logo-dark.png'. Physical path: 'E:\dev\SELFSERVICE\src\SELFSERVICE.Web\wwwroot\images\logo\logo-dark.png'
    [19:22:29 INF] Request finished HTTP/2 GET https://localhost:44345/images/logo/logo-dark.png - - - 200 4236 image/png 3.0548ms
    [19:22:36 DBG] Executing HealthCheck collector HostedService. 
    
  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    I've tried with v5.2.1 as you said but couldn't reproduce that exception. Can you please share the steps to reproduce?

  • User Avatar
    0
    Mikael created

    If you do this within a tenant, there is a known issue fixed in 5.3.0-RC1 : https://support.abp.io/QA/Questions/2882

    BUT 5.3.0-RC1 bring another bug. Hoping it will be solved in the next release.

  • User Avatar
    0
    Dicky.tech@gmail.com created

    Hope so.

    Its a critical piece

  • User Avatar
    0
    Dicky.tech@gmail.com created

    I've tried with v5.2.1 as you said but couldn't reproduce that exception. Can you please share the steps to reproduce?

    Means 5.2.1 doesnt have the mentioned bug ?

  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    We have validated the problem. We'll be working on the next patch version. I'll share with you a workaround as soon as possible.

  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    This problem has been already solved in v5.2.2.

    Since It's an entity related problem and can't override or replace entity class. So I can't suggest to you a workaround now, you can update to 5.2.2


    Also your credit is refunded

  • User Avatar
    0
    enisn created
    Support Team .NET Developer

    Hi again.

    For earlier version such as yours, you can add following class into your Domain project and replace & override the QuestionManager with the fixed code block.

    I personally don't recommend to set protected or private properties via using reflection but in that case, it can be patched like this.

    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Volo.Abp.DependencyInjection;
    using Volo.Abp.Domain.Repositories;
    using Volo.Abp.Guids;
    using Volo.Abp.MultiTenancy;
    using Volo.Forms;
    using Volo.Forms.Forms;
    using Volo.Forms.Questions;
    using Volo.Forms.Questions.ChoosableItems;
    
    namespace YourProjectName;
    
    [ExposeServices(typeof(QuestionManager))]
    [Dependency(ReplaceServices = true)]
    public class MyQuestionManager : QuestionManager
    {
        protected IQuestionRepository questionRepository;
        public MyQuestionManager(
            IQuestionRepository questionRepository,
            IFormRepository formRepository,
            IGuidGenerator guidGenerator) : base(questionRepository, formRepository, guidGenerator)
        {
            this.questionRepository = questionRepository;
        }
    
        public override async Task<QuestionBase> UpdateAsync(Guid id, string title, int index, bool isRequired, string description, QuestionTypes questionType, bool hasOtherOption, List<(Guid Id, string value, bool isCorrect)> choiceList)
        {        
            var question = await questionRepository.GetAsync(id);
            var questionId = question.Id;
            var formId = question.FormId;
            var creationDate = question.CreationTime;
            // This will be removed when EfCore bug is resolved: https://github.com/dotnet/efcore/issues/22016
            // Since item with choice collection can't return single object; we can't remove choices over item.
            await ClearItemChoicesAsync(question);
            question = await questionRepository.GetAsync(id);
            await questionRepository.HardDeleteAsync(question, autoSave: true);
            var createdQuestion = CreateItemBasedOnType(questionType, questionId);
            createdQuestion
                .SetFormId(formId)
                .SetTitle(title)
                .SetIndex(index)
                .SetDescription(description);
            createdQuestion.SetRequired(isRequired);
            createdQuestion.SetOtherOption(hasOtherOption);
            if (createdQuestion is IChoosable choosableItem)
            {
                if (!(question is IChoosable))
                {
                    for (var i = 0; i < choiceList.Count; i++)
                    {
                        choosableItem.AddChoice(id: GuidGenerator.Create(), index: i + 1, value: choiceList[i].value, isCorrect: choiceList[i].isCorrect);
                    }
                }
                else
                {
                    UpdateIndexesOfChoiceList(choiceList);
                    choosableItem.AddChoices(choiceList);
                }
            }
    
            createdQuestion.CreationTime = creationDate;
            createdQuestion.LastModificationTime = DateTime.Now;
            FixChoicesTenants(createdQuestion);
            await UpdateFormLastModificationDateAsync(createdQuestion.FormId);
            return await questionRepository.InsertAsync(createdQuestion, true);
        }
    
        private void FixChoicesTenants(QuestionBase createdQuestion)
        {
            if(createdQuestion is Checkbox checkbox)
            {
                foreach(var choice in checkbox.Choices)
                {
                    SetProperty(choice, nameof(IMultiTenant.TenantId), CurrentTenant.Id);
                }
            }
    
            if (createdQuestion is ChoiceMultiple choiceMultiple)
            {
                  foreach(var choice in choiceMultiple.Choices)
                {
                    SetProperty(choice, nameof(IMultiTenant.TenantId), CurrentTenant.Id);
                }
            }
    
            if (createdQuestion is DropdownList dropdownList)
            {
                  foreach(var choice in dropdownList.Choices)
                {
                    SetProperty(choice, nameof(IMultiTenant.TenantId), CurrentTenant.Id);
                }
            }
        }
    
        private void SetProperty<T>(T obj, string propertyName, object value)
        {
            typeof(T).GetProperty(propertyName)?.SetValue(obj, value);
        }
    }
    
  • User Avatar
    0
    Dicky.tech@gmail.com created

    This problem has been already solved in v5.2.2.

    Since It's an entity related problem and can't override or replace entity class. So I can't suggest to you a workaround now, you can update to 5.2.2


    Also your credit is refunded

    Have update my project to 5.2.2. At least i can create questions with options/ choice responses. But when submitting the filled form i get below error. Seems the tenant id is not filled in the DB yet the form requires log in hence hence user is already in a tenant when filling the form.

  • User Avatar
    0
    gterdem created
    Senior .NET Developer

    I couldn't reproduce the error.

    Did you try creating a new form after updating to 5.2.2 and add questions / answers to newly created form?

  • User Avatar
    0
    Mikael created

    This is the same issue as reported here (applies to 5.2.2 and 5.3.0-RC1): https://support.abp.io/QA/Questions/3067/530-RC1-Form-Multi-tenant-issue

  • User Avatar
    0
    Dicky.tech@gmail.com created

    I couldn't reproduce the error.

    Did you try creating a new form after updating to 5.2.2 and add questions / answers to newly created form?

    I created a new form ans added questions. The problem persists.

  • User Avatar
    0
    gterdem created
    Senior .NET Developer

    This is the same issue as reported here (applies to 5.2.2 and 5.3.0-RC1): https://support.abp.io/QA/Questions/3067/530-RC1-Form-Multi-tenant-issue

    Yes, they seem same issue.

    Thank you, we'll investigate more based on the steps in https://support.abp.io/QA/Questions/3067/530-RC1-Form-Multi-tenant-issue

Made with ❤️ on ABP v9.1.0-preview. Updated on December 05, 2024, 12:19