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

Specify CultureInfo in Controller make query not working #18831

Closed
utarn opened this issue Nov 10, 2019 · 18 comments · Fixed by #18873 or #23052
Closed

Specify CultureInfo in Controller make query not working #18831

utarn opened this issue Nov 10, 2019 · 18 comments · Fixed by #18873 or #23052
Assignees
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported Servicing-approved type-bug
Milestone

Comments

@utarn
Copy link

utarn commented Nov 10, 2019

I want to force the user UI to be in Thai language. So, I set cultureinfo using this code.

var cultureInfo = CultureInfo.GetCultureInfo("th-TH");
Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = cultureInfo;

I also tried app.UseRequestLocalization and added only "th-TH" supported.
It's working fine on windows. But not in linux. I have tried running on asp.net core running docker image from mcr.microsoft.com. Still, it didn't work. I also tried on CentOS within and outside the container. It produces the same issue.

After adding this code, on Windows, the date time is rendered in Thai format properly. When running kestrel on linux and the query with parameter (Where clause) is specified in LINQ, it throws an exception.

PostgresException: 42703: column "__normalizedusername_0" does not exist

Steps to reproduce

Add this code.

var cultureInfo = CultureInfo.GetCultureInfo("th-TH");
Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = cultureInfo;

and try running

await _userManager.FindByNameAsync(username_to_test);

Output on /Identity/Account/Login

Npgsql.NpgsqlConnector+<>c__DisplayClass160_0+<<DoReadMessage>g__ReadMessageLong|0>d.MoveNext()
Npgsql.NpgsqlConnector+<>c__DisplayClass160_0+<<DoReadMessage>g__ReadMessageLong|0>d.MoveNext()
Npgsql.NpgsqlDataReader.NextResult(bool async, bool isConsuming)
Npgsql.NpgsqlCommand.ExecuteReaderAsync(CommandBehavior behavior, bool async, CancellationToken cancellationToken)
Npgsql.NpgsqlCommand.ExecuteDbDataReaderAsync(CommandBehavior behavior, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor+AsyncQueryingEnumerable<T>+AsyncEnumerator.MoveNextAsync()
System.Runtime.CompilerServices.ValueTaskAwaiter<TResult>.GetResult()
Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync<TSource>(IAsyncEnumerable<TSource> asyncEnumerable, CancellationToken cancellationToken)
Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync<TSource>(IAsyncEnumerable<TSource> asyncEnumerable, CancellationToken cancellationToken)
Microsoft.AspNetCore.Identity.UserManager<TUser>.FindByNameAsync(string userName)
Microsoft.AspNetCore.Identity.SignInManager<TUser>.PasswordSignInAsync(string userName, string password, bool isPersistent, bool lockoutOnFailure)
eSignatureWebApp.Areas.Identity.Pages.Account.LoginModel.OnPostAsync(string returnUrl) in Login.cshtml.cs

Further technical details

EF Core version: 3.0.0
Database provider: Npgsql 4.1.1 and Npgsql.EntityframeworkCore.Postgresql 3.0.1
Target framework: .net core 3.0
Operating system: CentOS 7 within container, CentOS 7, container mcr.microsoft.com/dotnet/core/aspnet:3.0
IDE: Visual Studio 2019

@utarn utarn added the type-bug label Nov 10, 2019
@ajcvickers
Copy link
Member

@roji Any thoughts here? Could this be a Linux config issue?

@roji
Copy link
Member

roji commented Nov 11, 2019

@utarn could you please submit a minimal project triggering the issue?

@utarn
Copy link
Author

utarn commented Nov 12, 2019

@roji I'm trying to create a new simple project but still not able to reproduce the issue. Please wait.

@utarn
Copy link
Author

utarn commented Nov 12, 2019

Now I'm have managed to reproduce the error. I put it here. https://github.com/utarn/testculture. Also the docker-compose file I use to test.

both

   var supportedCultures = new[]
{
                new CultureInfo("th-TH"),
};

app.UseRequestLocalization(new RequestLocalizationOptions
           {
               DefaultRequestCulture = new RequestCulture("th-TH"),
                // Formatting numbers, dates, etc.
                SupportedCultures = supportedCultures,
                // UI strings that we have localized.
                SupportedUICultures = supportedCultures
            });

and

  public class InternationalizationAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            var cultureInfo = CultureInfo.GetCultureInfo("th-TH");
            Thread.CurrentThread.CurrentCulture = cultureInfo;
            Thread.CurrentThread.CurrentUICulture = cultureInfo;
        }
    }

then put [Internationalization] on controller class.

both produce the same error.
After running, just try to put anythings in login page.

Expected behavior: Invalid login attempt.

Output:
PostgresException: 42703: column "__normalizedusername_0" does not exist

This also happens in another controller where I have parameter type int or string too.

@roji
Copy link
Member

roji commented Nov 12, 2019

Confirmed this is a bug in EF Core, submitted fix.

@roji roji added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Nov 12, 2019
@roji roji self-assigned this Nov 12, 2019
@roji roji added this to the 5.0.0 milestone Nov 12, 2019
roji added a commit that referenced this issue Nov 13, 2019
@mbp
Copy link

mbp commented Nov 20, 2019

We have this issue in production. We would really like this fix in 3.1. Why is it needed to wait until 5.0? Clearly a bug. It did work in 2.2.

@ErikEJ
Copy link
Contributor

ErikEJ commented Nov 20, 2019

Can you implement a workaround in Postgres provider, @roji ?

@roji
Copy link
Member

roji commented Nov 21, 2019

@ajcvickers what do you think?

@roji
Copy link
Member

roji commented Nov 21, 2019

At the very worst, it's possible to work around this by extending the SqlGenerationHelper of the provider you're using and override GenerateParameterName.

@mbp
Copy link

mbp commented Nov 21, 2019

I have implemented suggested work-around and it appears to work

Will show solution here if anyone else needs it. But I do believe this change would be nice to get into mainline, seems really trivial fix.

public class OrdinalCompareNpgsqlGenerationHelper : NpgsqlSqlGenerationHelper
{
    public OrdinalCompareNpgsqlGenerationHelper(RelationalSqlGenerationHelperDependencies dependencies) 
         : base(dependencies)
    {
    }

    public override string GenerateParameterName(string name)
        => name.StartsWith("@", StringComparison.Ordinal)
            ? name
            : "@" + name;
}
var dbContextOption = new DbContextOptionsBuilder<T>()
    .UseNpgsql(dbConnectionOptions.ConnectionString)
    .ReplaceService<ISqlGenerationHelper, OrdinalCompareNpgsqlGenerationHelper>()

@ajcvickers ajcvickers removed this from the 5.0.0 milestone Nov 22, 2019
@roji
Copy link
Member

roji commented Nov 25, 2019

We already fixed this in the 5.0 branch, so the first 5.0 preview will already contain this fix. At the moment we don't plan to patch this in 3.x, since the workaround is very easy and not many people are affected.

@smitpatel
Copy link
Contributor

PR not merged yet.

wtgodbe pushed a commit that referenced this issue Nov 10, 2020
@ultimaweapon
Copy link

When 3.1.11 that contains this fix will be released? I have some reasons that cannot move to 5.0. If it is not going to release soon I will use workaround instead.

@wtgodbe
Copy link
Member

wtgodbe commented Jan 11, 2021

When 3.1.11 that contains this fix will be released?

Tomorrow (January 12th)

@Tim1104
Copy link

Tim1104 commented Mar 9, 2021

Same issue

@roji
Copy link
Member

roji commented Mar 9, 2021

@Tim1104 are you seeing this issue when using EF Core 5.0? If so, can you please open a new issue with a runnable code sample that shows the bug you're seeing?

@Tim1104
Copy link

Tim1104 commented Mar 9, 2021

did this issue fixed in 3.1.11?

@roji
Copy link
Member

roji commented Mar 9, 2021

Yes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported Servicing-approved type-bug
Projects
None yet
9 participants