Open Closed

Error when clicking Setting button in the Form module #1975


User avatar
0
nhontran created
  • ABP Framework version: v4.4.3
  • UI type: MVC
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes / no
  • Exception message and stack trace:
  • Steps to reproduce the issue:"

Hi Abp support team, we are exploring the "Form" module in the latest version (4.4.3) and got 500 error when clicking the Setting button, below are the screenshot and the log

[17:20:13 INF] Executing endpoint '/Forms/Questions/EditSettingsModal' [17:20:13 INF] Route matched with {page = "/Forms/Questions/EditSettingsModal", action = "", controller = "", area = ""}. Executing page /Forms/Questions/EditSettingsModal [17:20:13 INF] Skipping the execution of current filter as its not the most effective filter implementing the policy Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy [17:20:13 INF] Executing handler method Volo.Forms.Web.Pages.Forms.Questions.EditSettingsModalModel.OnGetAsync - ModelState is Valid [17:20:13 ERR] ---------- RemoteServiceErrorInfo ---------- { "code": null, "message": "An internal error occurred during your request!", "details": null, "data": {}, "validationErrors": null } [17:20:13 ERR] Missing path parameter value for id (id) Volo.Abp.AbpException: Missing path parameter value for id (id) at Volo.Abp.Http.Client.DynamicProxying.UrlBuilder.ReplacePathVariables(StringBuilder urlBuilder, IList1 actionParameters, IReadOnlyDictionary2 methodArguments, ApiVersionInfo apiVersion) at Volo.Abp.Http.Client.DynamicProxying.UrlBuilder.GenerateUrlWithParameters(ActionApiDescriptionModel action, IReadOnlyDictionary2 methodArguments, ApiVersionInfo apiVersion) at Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor1.MakeRequestAsync(IAbpMethodInvocation invocation) at Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor1.MakeRequestAndGetResultAsync[T](IAbpMethodInvocation invocation) at Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor1.GetResultAsync(Task task, Type resultType) at Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor1.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func3 proceed) at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo) at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Validation.ValidationInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func3 proceed) at Volo.Forms.Web.Pages.Forms.Questions.EditSettingsModalModel.OnGetAsync() at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.NonGenericTaskHandlerMethod.Execute(Object receiver, Object[] arguments) at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeHandlerMethodAsync() at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeNextPageFilterAsync() [17:20:13 INF] Executing ObjectResult, writing value of type 'Volo.Abp.Http.RemoteServiceErrorResponse'. [17:20:13 INF] Executed page /Forms/Questions/EditSettingsModal in 22.8952ms [17:20:13 INF] Executed endpoint '/Forms/Questions/EditSettingsModal'

Could you please help us check?

Thank you.


14 Answer(s)
  • User Avatar
    0
    gterdem created
    Support Team Senior .NET Developer

    I tried on both 4.3.3 version and preview 5.0 versions but couldn't reproduce the error. Can you share more details?

    Is it a tiered application or non-tiered? Can you reproduce it after updating to 5.0 preview?

  • User Avatar
    0
    nhontran created

    Hi @gterdem, I just tested it using new project with version 4.4.3 and still got the same issue, it's a tiered application.

    I have not tried with the version 5.0 preview, as we dont have intention to upgrade it yet, can we check on version 4.4.3 instead?

  • User Avatar
    0
    gterdem created
    Support Team Senior .NET Developer

    I am sorry, I misspell it, I tried on 4.4.3, not 4.3.3.

    Can you share the project that you reproduced to support@abp.io?

  • User Avatar
    0
    nhontran created

    Hi @gterdem, I just sent the source code to support@abp.io

    Please help me check, thank you.

  • User Avatar
    0
    gterdem created
    Support Team Senior .NET Developer

    Thank you, I have checked and reproduced the problem.

    Fixed the related issue, it should be available in the next release.

  • User Avatar
    0
    nhontran created

    Hi @gterdem, thanks a lot for checking and update.

    May I know what is the root cause? is there any workaround for this issue instead of waiting for the next release?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you try below:

    [RemoteService(Name = FormsRemoteServiceConsts.RemoteServiceName)]
    [Area("form")]
    [ControllerName("Form")]
    [Route("api/forms")]
    [Authorize(FormsPermissions.Forms.Default)]
    public class MyFormController : AbpControllerBase, IFormAppService
    {
    	protected IFormAppService FormAppService { get; }
    
    	public MyFormController(IFormAppService formAppService)
    	{
    		FormAppService = formAppService;
    		LocalizationResource = typeof(FormsResource);
    	}
    
    	[HttpGet]
    	public virtual Task<PagedResultDto<FormDto>> GetListAsync(GetFormListInputDto input)
    	{
    		return FormAppService.GetListAsync(input);
    	}
    
    	[HttpGet]
    	[Route("{id}/responses")]
    	public Task<PagedResultDto<FormResponseDetailedDto>> GetResponsesAsync(Guid id, GetResponseListInputDto input)
    	{
    		return FormAppService.GetResponsesAsync(id, input);
    	}
    
    	[HttpGet]
    	[Route("{id}/download-responses-csv")]
    	public Task<IRemoteStreamContent> GetCsvResponsesAsync(Guid id, GetResponseListInputDto input)
    	{
    		return FormAppService.GetCsvResponsesAsync(id, input);
    	}
    
    	[HttpGet]
    	[Route("{id}/responses-count")]
    	public Task<long> GetResponsesCountAsync(Guid id)
    	{
    		return FormAppService.GetResponsesCountAsync(id);
    	}
    
    	[HttpDelete]
    	[Route("{id}/responses")]
    	public Task DeleteAllResponsesOfFormAsync(Guid id)
    	{
    		return FormAppService.DeleteAllResponsesOfFormAsync(id);
    	}
    
    	[HttpPost]
    	[Route("/invite")]
    	public Task SendInviteEmailAsync(FormInviteEmailInputDto input)
    	{
    		return FormAppService.SendInviteEmailAsync(input);
    	}
    
    	[HttpPost]
    	public virtual Task<FormDto> CreateAsync(CreateFormDto input)
    	{
    		return FormAppService.CreateAsync(input);
    	}
    
    	[AllowAnonymous]
    	[HttpGet]
    	[Route("{id}")]
    	public virtual Task<FormWithDetailsDto> GetAsync(Guid id)
    	{
    		return FormAppService.GetAsync(id);
    	}
    
    	[HttpPut]
    	[Route("{id}")]
    	public virtual Task<FormDto> UpdateAsync(Guid id, UpdateFormDto input)
    	{
    		return FormAppService.UpdateAsync(id, input);
    	}
    
    	[HttpPut]
    	[Route("{id}/settings")]
    	public virtual Task SetSettingsAsync(Guid id, UpdateFormSettingInputDto input)
    	{
    		return FormAppService.SetSettingsAsync(id, input);
    	}
    
    	[HttpGet]
    	[Route("{id}/settings")]
    	public virtual Task<FormSettingsDto> GetSettingsAsync(Guid id)
    	{
    		return FormAppService.GetSettingsAsync(id);
    	}
    
    	[AllowAnonymous]
    	[HttpGet]
    	[Route("{id}/questions")]
    	public virtual Task<List<QuestionDto>> GetQuestionsAsync(Guid id, GetQuestionListDto input)
    	{
    		return FormAppService.GetQuestionsAsync(id, input);
    	}
    
    	[HttpPost]
    	[Route("{id}/questions")]
    	public virtual Task<QuestionDto> CreateQuestionAsync(Guid id, CreateQuestionDto input)
    	{
    		return FormAppService.CreateQuestionAsync(id, input);
    	}
    
    	[HttpDelete]
    	[Route("{id}")]
    	public virtual Task DeleteAsync(Guid id)
    	{
    		return FormAppService.DeleteAsync(id);
    	}
    }
    
    public class MyServiceConvention : IApplicationModelConvention
    {
        public virtual void Apply(ApplicationModel application)
        {
            application.Controllers.RemoveAll(x => x.ControllerType == typeof(Volo.Forms.Forms.FormController));
        }
    }
    
    public override void ConfigureServices(ServiceConfigurationContext context)
    {
        var hostingEnvironment = context.Services.GetHostingEnvironment();
        var configuration = context.Services.GetConfiguration();
    
        Configure<MvcOptions>(mvcOptions =>
        {
            mvcOptions.Conventions.Add(new MyServiceConvention());
        });
    }
    
  • User Avatar
    0
    nhontran created

    Hi @maliming, the AbpControllerBase, IFormAppService are not available, do you mean AbpController, IFormApplicationService?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Yes, Can you try?

  • User Avatar
    0
    nhontran created

    Hi @maliming, it does not work.

    First, the IFormApplicationService does not contain the GetCsvResponsesAsync() method:

            [HttpGet]
            [Route("{id}/download-responses-csv")]
            public Task<IRemoteStreamContent> GetCsvResponsesAsync(Guid id, GetResponseListInputDto input)
            {
                return FormAppService.GetCsvResponsesAsync(id, input);
            }
    

    so, I have tried comment out this method and follow the rest, and got this error

    Microsoft.AspNetCore.Routing.Matching.AmbiguousMatchException: The request matched multiple endpoints. Matches: 
    Volo.Forms.Forms.FormController.GetListAsync (Volo.Forms.HttpApi)
    test.formsurvey.Controllers.MyFormController.GetListAsync (test.formsurvey.HttpApi)
    

    Can you help try on your side first?

    Thank you.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you share your project with me? liming.ma@volosoft.com

  • User Avatar
    0
    nhontran created

    just sent you the project, thanks.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    The new MyFormController.

    
    using Microsoft.AspNetCore.Authorization;
    using Microsoft.AspNetCore.Mvc;
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using CsvHelper;
    using CsvHelper.Configuration;
    using Volo.Abp;
    using Volo.Abp.Application.Dtos;
    using Volo.Abp.AspNetCore.Mvc;
    using Volo.Forms;
    using Volo.Forms.Forms;
    using Volo.Forms.Localization;
    using Volo.Forms.Permissions;
    using Volo.Forms.Questions;
    using Volo.Forms.Responses;
    
    namespace test.formsurvey.Controllers
    {
    	[RemoteService(Name = FormsRemoteServiceConsts.RemoteServiceName)]
    	[Area("form")]
    	[ControllerName("Form")]
    	[Route("api/forms")]
    	[Authorize(FormsPermissions.Forms.Default)]
    	public class MyFormController : AbpController, IFormApplicationService
        {
            protected IFormApplicationService FormApplicationService { get; }
    
            public MyFormController(IFormApplicationService formApplicationService)
            {
                FormApplicationService = formApplicationService;
                LocalizationResource = typeof(FormsResource);
            }
    
            [HttpGet]
            public virtual Task<PagedResultDto<FormDto>> GetListAsync(GetFormListInputDto input)
            {
                return FormApplicationService.GetListAsync(input);
            }
    
            [HttpGet]
            [Route("{id}/responses")]
            public Task<PagedResultDto<FormResponseDetailedDto>> GetResponsesAsync(Guid id, GetResponseListInputDto input)
            {
                return FormApplicationService.GetResponsesAsync(id, input);
            }
    
            [HttpGet]
            [Route("{id}/responses-count")]
            public Task<long> GetResponsesCountAsync(Guid id)
            {
                return FormApplicationService.GetResponsesCountAsync(id);
            }
    
            [HttpDelete]
            [Route("{id}/responses")]
            public Task DeleteAllResponsesOfFormAsync(Guid id)
            {
                return FormApplicationService.DeleteAllResponsesOfFormAsync(id);
            }
    
            [HttpPost]
            [Route("/invite")]
            public Task SendInviteEmailAsync(FormInviteEmailInputDto input)
            {
                return FormApplicationService.SendInviteEmailAsync(input);
            }
    
            [HttpGet]
            [Route("{id}/download-responses-csv")]
            public async Task<IActionResult> ExportCsvAsync(Guid id, GetResponseListInputDto input)
            {
                var form = await FormApplicationService.GetAsync(id);
                var questions = form.Questions.OrderBy(q => q.Index).ToList();
                var responseList =
                    await FormApplicationService.GetResponsesAsync(id, new GetResponseListInputDto
                    {
                        Sorting = "id asc"
                    });
    
                var headers = questions.Select(q => q.Title).ToList();
                headers.AddFirst("Date");
    
                var csvConfiguration = new CsvConfiguration(new CultureInfo(CultureInfo.CurrentUICulture.Name))
                {
                    ShouldQuote = (field, context) => true
                };
    
                using (var memoryStream = new MemoryStream())
                {
                    using (var streamWriter = new StreamWriter(stream: memoryStream, encoding: new UTF8Encoding(true)))
                    {
                        using (var csvWriter = new CsvWriter(streamWriter, csvConfiguration))
                        {
                            foreach (var header in headers)
                            {
                                csvWriter.WriteField(header);
                            }
    
                            foreach (var response in responseList.Items)
                            {
                                await csvWriter.NextRecordAsync();
    
                                var date = response.LastModificationTime ?? response.CreationTime;
    
                                csvWriter.WriteField(date.ToString("yyyy-MM-dd HH:mm:ss"));
    
                                foreach (var question in questions)
                                {
                                    var questionResponse = response.Answers.FirstOrDefault(x => x.QuestionId == question.Id);
    
                                    csvWriter.WriteField(questionResponse?.Value ?? string.Empty);
                                }
                            }
                        }
    
                        await memoryStream.FlushAsync();
    
                        var file = File(memoryStream.ToArray(), "text/csv",
                            $"{form.Title}.csv");
    
                        return file;
                    }
                }
            }
    
            [HttpPost]
            public virtual Task<FormDto> CreateAsync(CreateFormDto input)
            {
                return FormApplicationService.CreateAsync(input);
            }
    
            [AllowAnonymous]
            [HttpGet]
            [Route("{id}")]
            public virtual Task<FormWithDetailsDto> GetAsync(Guid id)
            {
                return FormApplicationService.GetAsync(id);
            }
    
            [HttpPut]
            [Route("{id}")]
            public virtual Task<FormDto> UpdateAsync(Guid id, UpdateFormDto input)
            {
                return FormApplicationService.UpdateAsync(id, input);
            }
    
            [HttpPut]
            [Route("{id}/settings")]
            public virtual Task SetSettingsAsync(Guid id, UpdateFormSettingInputDto input)
            {
                return FormApplicationService.SetSettingsAsync(id, input);
            }
    
            [HttpGet]
            [Route("{formId}/settings")]
            public virtual Task<FormSettingsDto> GetSettingsAsync(Guid formId)
            {
                return FormApplicationService.GetSettingsAsync(formId);
            }
    
            [AllowAnonymous]
            [HttpGet]
            [Route("{id}/questions")]
            public virtual Task<List<QuestionDto>> GetQuestionsAsync(Guid id, GetQuestionListDto input)
            {
                return FormApplicationService.GetQuestionsAsync(id, input);
            }
    
            [HttpPost]
            [Route("{id}/questions")]
            public virtual Task<QuestionDto> CreateQuestionAsync(Guid id, CreateQuestionDto input)
            {
                return FormApplicationService.CreateQuestionAsync(id, input);
            }
    
            [HttpDelete]
            [Route("{id}")]
            public virtual Task DeleteAsync(Guid id)
            {
                return FormApplicationService.DeleteAsync(id);
            }
        }
    }
    
    
  • User Avatar
    0
    nhontran created

    Hi @maliming, it works now.

    Thanks a lot for your support :)

Made with ❤️ on ABP v8.2.0-preview Updated on March 25, 2024, 15:11