question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Application module decimal localization

See original GitHub issue

Hi,

I try to send ajax request to AppService with model that has decimal property and my UI culture is “ro-RO”. I get this error:

Method arguments are not valid! See ValidationErrors for details.
AbpValidationException: Method arguments are not valid! See ValidationErrors for details.
Următoarele erori au fost detectate in timpul validării.
- Could not convert string to decimal: 1.000,00. Path 'suprafataTeren', line 1, position 628.
- Could not convert string to decimal: 1.000,00. Path 'suprafataConstructie', line 1, position 662.

STACK TRACE: 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)

If i pass it the same model using form submit to the controller it works fine. I think is something about DecimalModelBinder culture: https://github.com/aspnetboilerplate/aspnetboilerplate/blob/e0ded5d870/src/Abp.Web.Api/WebApi/AbpWebApiModule.cs#L146 If i change to English this works also fine in my AppService.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
totperocommented, Dec 4, 2020

Hi, I solve this issue by adding this json convertor:

public class CultureInvariantDecimalConverter : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            decimal dec = (decimal)value;
            if (dec == decimal.MinValue)
            {
                writer.WriteValue(string.Empty);
            }
            else
            {
                writer.WriteValue(dec);
            }
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
            JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.String)
            {
                if (reader.Value == null)
                {
                    return null;
                }
                if ((string)reader.Value == string.Empty)
                {
                    return decimal.MinValue;
                }
               
            }

            if (reader.Value == null) return null;
            if (decimal.TryParse(reader.Value.ToString(), NumberStyles.Any, CultureInfo.CurrentCulture, out var result))
            {
                return result;
            }
            //return Convert.ToDecimal(reader.Value.ToString(), CultureInfo.CurrentCulture);
            //throw new JsonSerializationException("Unexpected token type: " +
            //                                     reader.TokenType);
            return null;
        }

        public override bool CanConvert(Type objectType)
        {
            return (objectType == typeof(decimal) || objectType == typeof(decimal?));
        }
    }

And in startup.cs:

 public IServiceProvider ConfigureServices(IServiceCollection services)
{
        //.....
       services.AddNewtonsoftJson(options =>
                {
                    options.SerializerSettings.Converters.Add(new CultureInvariantDecimalConverter());
                });
}

Related to https://stackoverflow.com/a/57221444/2327332

0reactions
totperocommented, Dec 3, 2020

Hi @totpero Can you please share the relevant part of the log.txt file

This is in my log after request:

INFO  2020-12-03 10:05:14,822 [9    ] Microsoft.AspNetCore.Hosting.Diagnostics - Request finished HTTP/1.1 GET http://localhost:62114/ - - - 500 - text/html;+charset=utf-8 2122.7943ms
INFO  2020-12-03 10:05:25,158 [10   ] Microsoft.AspNetCore.Hosting.Diagnostics - Request starting HTTP/1.1 POST http://localhost:62114/signalr/negotiate text/plain;charset=UTF-8 0
INFO  2020-12-03 10:05:25,162 [10   ] ft.AspNetCore.Routing.EndpointMiddleware - Executing endpoint '/signalr/negotiate'
INFO  2020-12-03 10:05:25,177 [10   ] ft.AspNetCore.Routing.EndpointMiddleware - Executed endpoint '/signalr/negotiate'
INFO  2020-12-03 10:05:25,182 [11   ] Microsoft.AspNetCore.Hosting.Diagnostics - Request finished HTTP/1.1 POST http://localhost:62114/signalr/negotiate text/plain;charset=UTF-8 0 - 200 273 application/json 23.6975ms
INFO  2020-12-03 10:05:25,187 [11   ] Microsoft.AspNetCore.Hosting.Diagnostics - Request starting HTTP/1.1 GET http://localhost:62114/signalr?id=A34-QFrSC5Ln42WReU0qmw - -
INFO  2020-12-03 10:05:25,195 [11   ] ft.AspNetCore.Routing.EndpointMiddleware - Executing endpoint '/signalr'
INFO  2020-12-03 10:05:25,252 [5    ] Microsoft.AspNetCore.Hosting.Diagnostics - Request starting HTTP/1.1 POST http://localhost:62114/signalr/negotiate text/plain;charset=UTF-8 0
INFO  2020-12-03 10:05:25,256 [5    ] ft.AspNetCore.Routing.EndpointMiddleware - Executing endpoint '/signalr/negotiate'
INFO  2020-12-03 10:05:25,257 [5    ] ft.AspNetCore.Routing.EndpointMiddleware - Executed endpoint '/signalr/negotiate'
INFO  2020-12-03 10:05:25,257 [11   ] Microsoft.AspNetCore.Hosting.Diagnostics - Request finished HTTP/1.1 POST http://localhost:62114/signalr/negotiate text/plain;charset=UTF-8 0 - 200 273 application/json 4.8054ms
DEBUG 2020-12-03 10:05:25,259 [10   ] Abp.AspNetCore.SignalR.Hubs.AbpCommonHub - A client is connected: {"ConnectionId":"A34-QFrSC5Ln42WReU0qmw","IpAddress":"::1","TenantId":14,"UserId":21,"ConnectTime":"2020-12-03T10:05:25.2208566+02:00","Properties":{}}
INFO  2020-12-03 10:05:25,261 [11   ] Microsoft.AspNetCore.Hosting.Diagnostics - Request starting HTTP/1.1 GET http://localhost:62114/signalr?id=w-V40G9QC2RpLWG8ISJseg - -
INFO  2020-12-03 10:05:25,263 [11   ] ft.AspNetCore.Routing.EndpointMiddleware - Executing endpoint '/signalr'
DEBUG 2020-12-03 10:05:25,269 [10   ] Abp.AspNetCore.SignalR.Hubs.AbpCommonHub - A client is connected: {"ConnectionId":"w-V40G9QC2RpLWG8ISJseg","IpAddress":"::1","TenantId":14,"UserId":21,"ConnectTime":"2020-12-03T10:05:25.2696342+02:00","Properties":{}}
INFO  2020-12-03 10:05:26,252 [11   ] Microsoft.AspNetCore.Hosting.Diagnostics - Request starting HTTP/1.1 POST http://localhost:62114/signalr/negotiate text/plain;charset=UTF-8 0
INFO  2020-12-03 10:05:26,254 [11   ] ft.AspNetCore.Routing.EndpointMiddleware - Executing endpoint '/signalr/negotiate'
INFO  2020-12-03 10:05:26,254 [11   ] ft.AspNetCore.Routing.EndpointMiddleware - Executed endpoint '/signalr/negotiate'
INFO  2020-12-03 10:05:26,255 [9    ] Microsoft.AspNetCore.Hosting.Diagnostics - Request finished HTTP/1.1 POST http://localhost:62114/signalr/negotiate text/plain;charset=UTF-8 0 - 200 273 application/json 3.0386ms
INFO  2020-12-03 10:05:26,259 [9    ] Microsoft.AspNetCore.Hosting.Diagnostics - Request starting HTTP/1.1 GET http://localhost:62114/signalr?id=gkKesy72lfGnlwYP9voyFw - -
INFO  2020-12-03 10:05:26,262 [9    ] ft.AspNetCore.Routing.EndpointMiddleware - Executing endpoint '/signalr'
DEBUG 2020-12-03 10:05:26,264 [11   ] Abp.AspNetCore.SignalR.Hubs.AbpCommonHub - A client is connected: {"ConnectionId":"gkKesy72lfGnlwYP9voyFw","IpAddress":"::1","TenantId":14,"UserId":21,"ConnectTime":"2020-12-03T10:05:26.2649243+02:00","Properties":{}}
INFO  2020-12-03 10:05:35,372 [10   ] Microsoft.AspNetCore.Hosting.Diagnostics - Request starting HTTP/1.1 POST http://localhost:62114/api/services/app/DocumentAdaptor/SaveCePf application/json 570
INFO  2020-12-03 10:05:35,376 [10   ] ft.AspNetCore.Routing.EndpointMiddleware - Executing endpoint 'MyAppNameTest.Documente.DocumentAdaptorAppService.SaveCePf (MyAppNameTest.Application)'
INFO  2020-12-03 10:05:35,385 [10   ] c.Infrastructure.ControllerActionInvoker - Route matched with {area = "app", action = "SaveCePf", controller = "DocumentAdaptor"}. Executing controller action with signature System.Threading.Tasks.Task SaveCePf(MyAppNameTest.Documente.MyModelTestDto) on controller MyAppNameTest.Documente.DocumentAdaptorAppService (MyAppNameTest.Application).
WARN  2020-12-03 10:05:36,546 [10   ] Mvc.ExceptionHandling.AbpExceptionFilter - Method arguments are not valid! See ValidationErrors for details.
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)
WARN  2020-12-03 10:05:36,546 [10   ] Mvc.ExceptionHandling.AbpExceptionFilter - There are 2 validation errors:
WARN  2020-12-03 10:05:36,546 [10   ] Mvc.ExceptionHandling.AbpExceptionFilter - Could not convert string to decimal: 1.111,00. Path 'suprafataTeren', line 1, position 189. (suprafataTeren)
WARN  2020-12-03 10:05:36,546 [10   ] Mvc.ExceptionHandling.AbpExceptionFilter - Could not convert string to decimal: 2.222,00. Path 'suprafataConstructie', line 1, position 223. (suprafataConstructie)
INFO  2020-12-03 10:05:36,702 [10   ] .Mvc.Infrastructure.ObjectResultExecutor - Executing ObjectResult, writing value of type 'Abp.Web.Models.AjaxResponse'.
INFO  2020-12-03 10:05:36,717 [10   ] c.Infrastructure.ControllerActionInvoker - Executed action MyAppNameTest.Documente.DocumentAdaptorAppService.SaveCePf (MyAppNameTest.Application) in 1332.097ms
INFO  2020-12-03 10:05:36,717 [10   ] ft.AspNetCore.Routing.EndpointMiddleware - Executed endpoint 'MyAppNameTest.Documente.DocumentAdaptorAppService.SaveCePf (MyAppNameTest.Application)'
INFO  2020-12-03 10:05:36,718 [17   ] Microsoft.AspNetCore.Hosting.Diagnostics - Request finished HTTP/1.1 POST http://localhost:62114/api/services/app/DocumentAdaptor/SaveCePf application/json 570 - 400 2122 application/json;+charset=utf-8 1345.8186ms

Read more comments on GitHub >

github_iconTop Results From Across the Web

Localized decimal numbers format - python
I want to print a number in a localized format with a thousands separator and two decimal digits. import locale locale.setlocale(locale.LC_ALL, ...
Read more >
Decimal fixed point and floating point arithmetic
The decimal module provides support for fast correctly rounded decimal floating point arithmetic. It offers several advantages over the float datatype: Decimal ......
Read more >
Localization
When you start an application, the system sets a default locale that the application uses to determine what decimal points and thousands separators...
Read more >
Customizing Formats (The Java™ Tutorials > ...
This class allows you to control the display of leading and trailing zeros, prefixes and suffixes, grouping (thousands) separators, and the decimal separator....
Read more >
How to deal with international data formats in Python
Handling the different decimal separators and date formats may seem like a hassle until you get acquainted with Python's locale module.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found