Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System.Globalization.CultureNotFoundException UnitsNet.ToString() on system that Culture information is not available #1238

Closed
PRIMETSS opened this issue Apr 11, 2023 · 8 comments · Fixed by #1266
Labels

Comments

@PRIMETSS
Copy link

PRIMETSS commented Apr 11, 2023

When .ToString() is called via DotNet #7 App on a UnitsNet Type on a system that either does not have Culture support with the
export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT='1' environment variable set (required to run dotnet on PI) in Culture Invariant mode.

Unhandled exception. System.TypeInitializationException: The type initializer for 'UnitsNet.UnitAbbreviationsCache' threw an exception. ---> System.Globalization.CultureNotFoundException: Only the invariant culture is supported in globalization-invariant mode. See https://aka.ms/GlobalizationInvariantMode for more information. (Parameter 'name') en-US is an invalid culture identifier. at System.Globalization.CultureInfo..ctor(String name, Boolean useUserOverride) at UnitsNet.UnitAbbreviationsCache..cctor() --- End of inner exception stack trace --- at UnitsNet.UnitAbbreviationsCache.get_Default() at UnitsNet.UnitFormatter.GetFormatArgs[TUnitType](TUnitType unit, Double value, IFormatProvider culture, IEnumerable1 args)
at UnitsNet.QuantityFormatter.ToStringWithSignificantDigitsAfterRadix[TUnitType](IQuantity1 quantity, IFormatProvider formatProvider, Int32 number) at UnitsNet.QuantityFormatter.Format[TUnitType](IQuantity1 quantity, String format, IFormatProvider formatProvider)
at UnitsNet.Temperature.ToString(String format, IFormatProvider provider)
at UnitsNet.Temperature.ToString(String format)
at UnitsNet.Temperature.ToString()`

On OpenWRT SNAPShot (r22514) (Busybox Linux-musl ARM64) running on a Raspberry PI CM4 install latest DotNet SDK Version: 7.0.202 an ' System.Globalization.CultureNotFoundException' is thrown.

Expected behavior

string temp = sensorAht20.GetTemperature().ToString("F2")

Expected to return a 2 decimal places Temperature, eg '22.2' on system where Culture is not available.

image

https://learn.microsoft.com/en-us/dotnet/core/runtime-config/globalization

@PRIMETSS PRIMETSS added the bug label Apr 11, 2023
@tmilnthorp
Copy link
Collaborator

Thanks for the info. This is an oversight in our fallback mechanism.

@angularsen I wonder if #1210 would be the best fix here.

@angularsen
Copy link
Owner

@tmilnthorp Yes I think we can solve it as part of that feature, maybe make a note to test this scenario.

@aradalvand
Copy link

Same issue here.
Any time frame as to when #1210 is likely to be merged?

@pgrawehr
Copy link
Contributor

@PRIMETSS Just curious: Why do you need that in the first place? Culture support works just fine on the Raspberry Pi (at least for me), so this setting seems unnecessary. Or is it the container you're using?

@PRIMETSS
Copy link
Author

To get DotNet 7/8 (Core) runtime to currently function on OpenWRT Busybox musl-linux using package icu71 you need to set export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT='1'

This package has now updated to icu72 recently, and have not checked if this removed that 'workaround' but from memory I think I still had same issue after.

image

@angularsen
Copy link
Owner

Will try to make some progress this weekend.

angularsen added a commit that referenced this issue Jun 18, 2023
…1210)

Fixes #1126 
Refs #1238 

A quick draft to move the unit abbreviations into resource files. I also want to move methods for getting culture-specific abbreviations to the individual quantities.

This should:
- Reduce initialization time by removing the MapGeneratedLocalizations methods (TODO)
- Reduce in-memory footprint by only loading a requested culture
- Allow formatting to use methods on the quantities themselves
  - Which should allow for better extensibility as well
- Remove the unit abbreviations cache (deprecate)

### TODOs
- [ ] Test fallback to invariant culture `export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT='1'` #1238 

---------

Co-authored-by: Andreas Gullberg Larsen <andreas.larsen84@gmail.com>
angularsen added a commit that referenced this issue Jun 18, 2023
Fixes #1238

Applications crashed when running on Linux or Raspberry PI systems if
.NET cultures were not installed.

Specifically, `UnitAbbreviationsCache.Default` threw an exception trying
to instantiate the fallback `CultureInfo` with `en-US`.

### Changes
- Change fallback culture to `InvariantCulture`
- Add `CultureHelper.GetCultureOrInvariant()` to handle
`CultureNotFoundException`
- Change `UnitInfo` to map invariant culture to `en-US` localization
@angularsen
Copy link
Owner

angularsen commented Jun 18, 2023

A possible fix is merged in #1266 , it would be good if you have the chance to build it locally and try it out. I have a few other fixes before I'm ready to publish a new nuget.

@angularsen
Copy link
Owner

#1266 is out in Release UnitsNet/5.22.0 · angularsen/UnitsNet

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants