Base solution for your next web application
Open Closed

AbpValidationException being thrown when language != english #9874


User avatar
0
kfrancis created

Prerequisites

  • What is your product version? 10.0.0
  • What is your product type (Angular or MVC)? MVC Jquery
  • What is product framework type (.net framework or .net core)? Net 5

We've developed a system using aspnetzero, works great. We're now down to testing other features that we didn't pay much attention to, like localization. We have a case where a modal popup works fine when the language is English, and fails (model binding with the view model, my guess) when the language is anything but english.

Stack Trace

WARN  2020-12-03 15:46:05,850 [64   ] Mvc.ExceptionHandling.AbpExceptionFilter - There are 6 validation errors:
WARN  2020-12-03 15:46:05,850 [64   ] Mvc.ExceptionHandling.AbpExceptionFilter - The value '0.2' is not valid. (PrimaryOpacities)
WARN  2020-12-03 15:46:05,850 [64   ] Mvc.ExceptionHandling.AbpExceptionFilter - The value '0.2' is not valid. (PrimaryOpacities)
WARN  2020-12-03 15:46:05,850 [64   ] Mvc.ExceptionHandling.AbpExceptionFilter - The value '0.2' is not valid. (PrimaryOpacities)
WARN  2020-12-03 15:46:05,850 [64   ] Mvc.ExceptionHandling.AbpExceptionFilter - The value '0.2' is not valid. (SecondaryOpacities)
WARN  2020-12-03 15:46:05,850 [64   ] Mvc.ExceptionHandling.AbpExceptionFilter - The value '0.2' is not valid. (SecondaryOpacities)
WARN  2020-12-03 15:46:05,850 [64   ] Mvc.ExceptionHandling.AbpExceptionFilter - The value '0.2' is not valid. (SecondaryOpacities)
INFO  2020-12-03 15:46:05,851 [64   ] c.Infrastructure.ControllerActionInvoker - Executed action PatientManagement.Web.Areas.App.Controllers.PatientsController.ViewSegmentModal (PatientManagement.Web.Mvc) in 609.1147ms
INFO  2020-12-03 15:46:05,851 [64   ] ft.AspNetCore.Routing.EndpointMiddleware - Executed endpoint 'PatientManagement.Web.Areas.App.Controllers.PatientsController.ViewSegmentModal (PatientManagement.Web.Mvc)'
ERROR 2020-12-03 15:46:05,852 [64   ] nostics.DeveloperExceptionPageMiddleware - An unhandled exception has occurred while executing the request.
Abp.Runtime.Validation.AbpValidationException: Method arguments are not valid! See ValidationErrors for details.
   at Abp.Runtime.Validation.Interception.MethodInvocationValidator.ThrowValidationError()
   at Abp.Runtime.Validation.Interception.MethodInvocationValidator.Validate()
   at Abp.AspNetCore.Mvc.Validation.AbpValidationActionFilter.OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
   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|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ExceptionContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at StackifyMiddleware.RequestTracerMiddleware.InvokeAsync(HttpContext context)
   at GraphQL.Server.Transports.AspNetCore.GraphQLHttpMiddleware`1.InvokeAsync(HttpContext context) in /_/src/Transports.AspNetCore/GraphQLHttpMiddleware.cs:line 50
   at StackExchange.Profiling.MiniProfilerMiddleware.Invoke(HttpContext context) in C:\projects\dotnet\src\MiniProfiler.AspNetCore\MiniProfilerMiddleware.cs:line 121
   at Microsoft.AspNetCore.Builder.Extensions.MapMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at IdentityServer4.Hosting.IdentityServerMiddleware.Invoke(HttpContext context, IEndpointRouter router, IUserSession session, IEventService events, IBackChannelLogoutService backChannelLogoutService)
   at IdentityServer4.Hosting.MutualTlsEndpointMiddleware.Invoke(HttpContext context, IAuthenticationSchemeProvider schemes)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at IdentityServer4.Hosting.BaseUrlMiddleware.Invoke(HttpContext context)
   at Abp.AspNetZeroCore.Web.Authentication.JwtBearer.JwtTokenMiddleware.&lt;&gt;c__DisplayClass0_0.&lt;&lt;UseJwtTokenMiddleware&gt;b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Abp.AspNetZeroCore.Web.Authentication.JwtBearer.JwtTokenMiddleware.&lt;&gt;c__DisplayClass0_0.&lt;&lt;UseJwtTokenMiddleware&gt;b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.ResponseCaching.ResponseCachingMiddleware.Invoke(HttpContext httpContext)
   at NWebsec.AspNetCore.Middleware.Middleware.MiddlewareBase.Invoke(HttpContext context)
   at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
INFO  2020-12-03 15:46:05,915 [12   ] Microsoft.AspNetCore.Hosting.Diagnostics - Request finished HTTP/1.1 POST http://localhost:63114/App/Patients/ViewSegmentModal application/x-www-form-urlencoded;+charset=UTF-8 434 - 500 - text/html;+charset=utf-8 685.3018ms

I know it says there are model violations, but it doesn't necessarily make sense here.

Here's the english XHR request:

Heres the french XHR request:

The view model is pretty simple:

public class SegmentModalViewModel 
{
     // other fields
     public double[] PrimaryOpacities { get; set; }
     public double[] SecondaryOpacities { get; set; }
}

4 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi @kfrancis

    Probably it is the decimal separator. Does that work when you use , as decimal separator in french ? If so, you need to handle it on the client side and use the correct separator for each language.

  • User Avatar
    0
    kfrancis created

    I sort of understand though I'm surprised that localization would have an effect in model binding. Is that expected? Is there any documentation about that effect?

  • User Avatar
    0
    kfrancis created

    Hmm, this sort of thing works if I apply it directly to the action method in question - but I can't seem to place this generally so that I don't need to markup everything to fix this:

    public class LocalizationPipeline
    {
        public void Configure(IApplicationBuilder applicationBuilder)
        {
            var supportedCultures = new[]
            {
                new CultureInfo("en-US"),
                new CultureInfo("fr")
            };
    
            var options = new RequestLocalizationOptions
            {
                DefaultRequestCulture = new RequestCulture(
                                           culture: "en-US",
                                           uiCulture: "en-US"),
                SupportedCultures = supportedCultures,
                SupportedUICultures = supportedCultures
            };
            options.RequestCultureProviders = new[]
                { new RouteDataRequestCultureProvider() {
                Options = options } };
    
            applicationBuilder.UseRequestLocalization(options);
        }
    }
    
    /// <summary>
    /// Load Modal when segment is clicked on.
    /// </summary>
    /// <param name="model">The Segment View Model from the ajax call</param>
    /// <returns></returns>
    [MiddlewareFilter(typeof(LocalizationPipeline))]
    public async Task<PartialViewResult> ViewSegmentModal(SegmentModalViewModel model)
    {
        // some work
    }
    

    In our solution, we're only supporting english and french (ontario standard).

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    Yes, this is how ASP.NET Core works by default. You can try to write a custmom model binder for decimal, see https://docs.microsoft.com/en-us/aspnet/core/mvc/models/model-binding?view=aspnetcore-5.0#custom-model-binders.