Skip to content

IgbSlider.GetCurrentValueAsync() returns a wrong value or throws, depending on browser locale #391

Description

@jsakamotoIGJP

Description

IgbSlider.GetCurrentValueAsync() (and its sync twin GetCurrentValue()) can return a wrong value, or throw an unhandled exception, depending on the browser's locale.

The returned value is parsed with double.Parse() without an explicit culture. This uses the current thread culture, and Blazor WebAssembly sets that culture from the browser's navigator.language.

When the locale uses a comma as the decimal separator (for example de-DE), a fractional value can be parsed into a much larger number. When the locale does not accept a period at all (for example fr-FR), the parse throws a FormatException that is not caught anywhere.

Data binding (@bind-Value and the ValueChanged event) is not affected. It goes through a different code path that is already culture safe. Only the explicit GetCurrentValueAsync() / GetCurrentValue() calls are affected.

Most apps read the slider value through data binding, so this bug may not hit many real projects. Still, GetCurrentValueAsync() is a public API and should return a correct value.

I found the same coding pattern (an async Get...Async() method that parses a double return value the same way) in a few other components. I have not verified these, but they are likely to have the same problem.

  • IgbCarousel.GetTotalAsync() / GetTotal()
  • IgbCarousel.GetCurrentAsync() / GetCurrent()
  • IgbHighlight.GetSizeAsync() / GetSize()
  • IgbHighlight.GetCurrentAsync() / GetCurrent()
  • IgbRating.GetCurrentValueAsync() / GetCurrentValue()

I reproduced this against a local build of the master branch, so it is not specific to any feature branch.

Hosting Model

Blazor WebAssembly

.NET Version

10.0 (the affected code is not framework specific, so earlier target frameworks are likely affected too)

Ignite UI for Blazor Version

Reproduced against a local build of master

Component / Area

Slider / Range Slider

Browser

Edge

Operating System

Windows

Steps to Reproduce

  1. Create a Blazor WebAssembly app and add the sample code below.
<main>
    <div>
        <p>Bound Value: @_boundValue</p>
    </div>
    <div>
        <p>
            <span>Retrieved Value: @_retrievedValue</span>
            <span>
                <IgbButton @onclick="RefreshValue">
                    GetCurrentValueAsync
                </IgbButton>
            </span>
        </p>
    </div>

    <IgbSlider @ref="_sliderRef"
               Min="0"
               Max="3"
               Step="0.5"
               PrimaryTicks="4"
               SecondaryTicks="1"
               HideSecondaryLabels
               @bind-Value="_boundValue">
    </IgbSlider>
</main>

@code
{
    private IgbSlider? _sliderRef;

    private double _boundValue = 1.0;

    private double? _retrievedValue;

    private async Task RefreshValue()
    {
        if (_sliderRef is not null)
        {
            _retrievedValue = await _sliderRef.GetCurrentValueAsync();
        }
    }
}
  1. Set the browser or OS display language to German (de-DE), so navigator.language returns "de-DE".
  2. Run the app. Move the slider to a value with a fractional part, for example 1.5.
  3. Click the GetCurrentValueAsync button and check the "Retrieved Value" line.
  4. Repeat with the display language set to French (fr-FR).

Actual Result

With de-DE, the retrieved value is wrong. For example, a slider value of 1.5 comes back as 15, with no error at all.

Image

With fr-FR, clicking the button throws an unhandled FormatException from GetCurrentValueAsync() whenever the slider value has a fractional part.

Image

In both cases, the "Bound Value" line always shows the correct value.

Expected Result

GetCurrentValueAsync() (and GetCurrentValue()) should return the correct value, no matter what locale the browser uses.

Reproduction URL

Attachments

I will attach a sample project

📦BlazorWasmApp1.zip

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions