Skip to content

Improve Error Message and/or Docs around InvariantGlobalization true by default #53678

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

Open
ardalis opened this issue Jan 28, 2024 · 3 comments
Labels
area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc design-proposal This issue represents a design proposal for a different issue, linked in the description NativeAOT
Milestone

Comments

@ardalis
Copy link
Contributor

ardalis commented Jan 28, 2024

I'd like to share some experience here. I just created a new webapi project and then added EF Core support. I didn't pay super close attention to the template's csproj file, as I assumed it would basically work as it has in the past. If I noticed the existence of this property it didn't jump out at me:

<InvariantGlobalization>true</InvariantGlobalization>

So, it came as a surprise to me when I had finished adding EF Core DbContext support and was using the CLI to create migrations, as I've done 100s of times in the past, and when I tried to update my localdb SQL Server I got this:

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.GetCultureInfo(String name)
   at Microsoft.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry, SqlConnectionOverrides overrides)
   at Microsoft.Data.SqlClient.SqlConnection.Open(SqlConnectionOverrides overrides)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerConnection.OpenDbConnection(Boolean errorsExpected)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenInternal(Boolean errorsExpected)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.<>c__DisplayClass18_0.<Exists>b__0(DateTime giveUp)
   at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.<>c__DisplayClass12_0`2.<Execute>b__0(DbContext _, TState s)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.ExecutionStrategyExtensions.Execute[TState,TResult](IExecutionStrategy strategy, TState state, Func`2 operation, Func`2 verifySucceeded)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.Exists(Boolean retryOnNotExists)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerDatabaseCreator.Exists()
   at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists()
   at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.UpdateDatabase(String targetMigration, String connectionString, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabaseImpl(String targetMigration, String connectionString, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.<>c__DisplayClass0_0.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
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.

Now, knowing I'd just created this project I was 100% sure I hadn't specified "en-us" anywhere in my code to configure and set up my DbContext. There's nothing in this that suggests I should look at my Web API project. The stack trace only includes EF Core types. Fortunately, my search led me to the setting and issues like this one:

dotnet/SqlClient#2239

(and probably this issue's existence will help others as well)

Proposal

Improve the error message shown above to suggest checking the application's project file to see if <InvariantCulture> has been set and, if so, to remove that setting (or set it to false).

Alternately, figure out a way to make local SQLServer development work with invariant culture.

@ardalis ardalis added the design-proposal This issue represents a design proposal for a different issue, linked in the description label Jan 28, 2024
@ghost ghost added the area-identity Includes: Identity and providers label Jan 28, 2024
@MackinnonBuck MackinnonBuck added NativeAOT area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc and removed area-identity Includes: Identity and providers labels Feb 5, 2024
@captainsafia
Copy link
Member

I just created a new webapi project

I believe we only set InvariantGlobalization=true when you use the AoT-enabled Web API template. Can you verify if this is the case?

Assuming so, @eerhardt do we document the fact that this is set for AoT templates anywhere?

@captainsafia captainsafia added this to the Discussions milestone Apr 30, 2024
@eerhardt
Copy link
Member

eerhardt commented May 1, 2024

I believe we only set InvariantGlobalization=true when you use the AoT-enabled Web API template. Can you verify if this is the case?

There was a time (8.0.0 - 8.0.1) where we were setting it in the webapi template regardless if you used AOT or not. This was fixed in 8.0.2 with #52461. If you are using the latest patches, this is now fixed.

do we document the fact that this is set for AoT templates anywhere?

I'm not sure and I don't know where that would be documented (maybe it should be on https://learn.microsoft.com/aspnet/core/fundamentals/native-aot?). This is basically a performance optimization. Since you are using AOT, we figured it makes sense to default to this mode. See #47029.

@ardalis
Copy link
Contributor Author

ardalis commented May 1, 2024

I wasn't using an AOT template (must've been 8.0.0-8.0.1). Sounds like this can probably be closed if it's resolved in the template (though I'd make sure the docs for AOT templates are clear about this).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-minimal Includes minimal APIs, endpoint filters, parameter binding, request delegate generator etc design-proposal This issue represents a design proposal for a different issue, linked in the description NativeAOT
Projects
None yet
Development

No branches or pull requests

5 participants
@ardalis @captainsafia @eerhardt @MackinnonBuck and others