更新 4:
哦哇,显然这不是 EF 或配置问题。
Somehow the .razor page variable assigment is messing up the data.
现在不知道如何继续处理这个问题,但我至少编辑了标题以反射(reflect)当前问题:Razor 页面在为字符串分配特殊字符时弄乱了编码。
问题:
无论我做什么,插入 MySQL 5.7.17 数据库的字符始终显示为 �:
尽管有类似的帖子,但没有一个解决方案对我有用,而且我已经耗尽了我的研究能力。
我尝试过的:
连接字符串上的“charset=utf8mb4”和“SET 字符集连接” SQL 命令: When using Entity Framework with MySQL, Unicode characters are replaced with basic characters
使用“utf8mb4”: MySQL charset=UTF-8 with ConnectionReset=True is not working
数据注释,如 [MySqlCharset("utf8mb4")]: https://dev.mysql.com/doc/connector-net/en/connector-net-entityframework-core-charset.html
在查询值上添加前缀 N: MySQL C# Text Encoding Problems
- 准备好的声明
- 在“OnModelCreating”上使用“IsUnicode(true)”
代码:
连接字符串:
"MySQL": "server=localhost;user=root;database=sgn;charset=utf8mb4;"
用户模型.cs
namespace source.Data.Models
{
[MySqlCharset("utf8mb4")]
[MySqlCollation("utf8mb4_unicode_ci")]
public class UserModel
{
public UserModel() { }
[Key]
public long Id { get; set; }
[MySqlCharset("utf8mb4")]
[MySqlCollation("utf8mb4_unicode_ci")]
public string Username { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Language { get; set; }
public string StartPage { get; set; }
}
}
DatabaseContext.cs
namespace source.Data.Database
{
public class DatabaseContext : DbContext
{
private IConfiguration Configuration;
public DbSet<UserModel> Users { get; set; }
public DatabaseContext(DbContextOptions<DatabaseContext> options, IConfiguration configuration)
: base(options)
{
Configuration = configuration;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder
.UseMySQL(Configuration.GetSection("AppSettings").GetSection("Database").GetSection("ConnectionString")["MySQL"]);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UserModel>().Property(p => p.Username).IsUnicode(true);
base.OnModelCreating(modelBuilder);
}
}
}
DesignTimeDatabaseContextFactory.cs
namespace source.Data.Database
{
public class DesignTimeDatabaseContextFactory : IDesignTimeDbContextFactory<DatabaseContext>
{
private IConfiguration Configuration;
private AppSettingsService AppSettings;
public DesignTimeDatabaseContextFactory()
{
}
public DesignTimeDatabaseContextFactory(IConfiguration configuration, AppSettingsService appSettings)
{
Configuration = configuration;
AppSettings = appSettings;
}
public DatabaseContext CreateDbContext(string[] args)
{
var builder = new DbContextOptionsBuilder<DatabaseContext>();
builder.UseMySQL(AppSettings.ConnectionString);
return new DatabaseContext(builder.Options, Configuration);
}
}
}
Create.razor - 这是我将用户添加到数据库的位置。请注意,该项目使用 Blazor,因此不要被“@functions”标签混淆。这两个函数都没有正确添加数据,注释是我尝试过的准备好的语句。
<div class="login_form">
<h3>Create Account</h3>
<button @onclick="@(e => AddEntry())">Add DB User!</button><br />
<button @onclick="@(e => AddEntry2())">Add TEST!</button><br />
</div>
@functions {
void AddEntry2()
{
UserModel test = new UserModel();
test.Username = "Test çã";
test.FirstName = "Michel";
test.LastName = "Arendt";
test.Email = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="fd909c9491bd9a909c9491d39e9290" rel="noreferrer noopener nofollow">[email protected]</a>";
test.Password = "123";
test.Language = "pt-BR";
test.StartPage = "/Home/";
db.Database.ExecuteSqlCommand("SET NAMES utf8mb4");
db.Database.ExecuteSqlCommand("SET character_set_connection = utf8mb4");
db.Database.ExecuteSqlCommand("INSERT INTO Users (Username) VALUES (N'" + test.Username + "')");
db.SaveChanges();
//using (SqlConnection connection = new SqlConnection(AppSettings.DatabaseConnectionString()))
//{
// connection.Open();
// SqlCommand command = new SqlCommand(null, connection);
// // Create and prepare an SQL statement.
// command.CommandText =
// "INSERT INTO Users (Username) " +
// "VALUES (@username)";
// SqlParameter username = new SqlParameter("@username", SqlDbType.NVarChar, 100);
// username.Value = "Garçon";
// command.Parameters.Add(username);
// // Call Prepare after setting the Commandtext and Parameters.
// command.Prepare();
// command.ExecuteNonQuery();
//}
}
void AddEntry()
{
UserModel waitress = new UserModel();
waitress.Username = "Garçon";
waitress.FirstName = "Test";
waitress.LastName = "Test";
waitress.Email = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="5835393134183f35393134763b3735" rel="noreferrer noopener nofollow">[email protected]</a>";
waitress.Password = "123";
waitress.Language = "pt-BR";
waitress.StartPage = "/Home/";
db.Users.Add(waitress);
db.SaveChanges();
}
}
source.csproj(依赖项引用)
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
<LangVersion>7.3</LangVersion>
<RestorePackages>false</RestorePackages>
<Version>0.10.0</Version>
<Authors>Michel Arendt</Authors>
<Product>SGN</Product>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Content Remove="compilerconfig.json" />
</ItemGroup>
<ItemGroup>
<None Include="compilerconfig.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="ElectronNET.API" Version="5.22.13" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.2.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.0.0-preview6.19304.6" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.2.0" />
<PackageReference Include="MySql.Data.EntityFrameworkCore" Version="8.0.16" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="4.5.0" />
</ItemGroup>
<ItemGroup>
<Content Update="electron.manifest.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>
数据库配置
数据库和列的默认排序规则和字符集分别为 utf8mb4_unicode_ci 和 utf8mb4:
Default database character set and collation
Columns character set and collation
关于我还可以尝试什么来解决这个问题或者我犯了什么错误,有什么想法吗?
提前致谢!
更新:
我按照 Bradley Grainger(评论)的建议切换到 Pomelo.EntityFrameworkCore.MySql,但这无助于解决问题。我更改的文件现在是:
将 Startup.cs 和 DesignTimeDatabaseContextFactory.cs 的构建更改为使用:
builder
.UseMySql(AppSettings.ConnectionString,
mysqlOptions =>
{
mysqlOptions
.CharSetBehavior(CharSetBehavior.AppendToAllColumns)
.AnsiCharSet(CharSet.Utf8mb4)
.UnicodeCharSet(CharSet.Utf8mb4);
});
创建.razor
void AddEntry2()
{
UserModel test = new UserModel();
test.Username = "Test çã";
test.FirstName = "Michel";
test.LastName = "Arendt";
test.Email = "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="523f333b3e12353f333b3e7c313d3f" rel="noreferrer noopener nofollow">[email protected]</a>";
test.Password = "123";
test.Language = "pt-BR";
test.StartPage = "/Home/";
using (MySqlConnection connection = new MySqlConnection(AppSettings.ConnectionString))
{
connection.Open();
MySqlCommand command = new MySqlCommand(null, connection);
// Create and prepare an SQL statement.
command.CommandText =
"INSERT INTO Users (Username) " +
"VALUES (@username)";
MySqlParameter username = new MySqlParameter("@username", MySqlDbType.LongText, 100);
username.Value = "Garçon";
command.Parameters.Add(username);
// Call Prepare after setting the Commandtext and Parameters.
command.Prepare();
command.ExecuteNonQuery();
}
}
认为这会有所帮助,因此我还在本地服务器上设置了 MySQL 初始化 (my.ini):
[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
但是,没有任何效果。还有其他想法吗?
更新2:
为了确定这是数据库问题还是 EF Core 问题,我设置了一个简单的 PHP 脚本来在数据库中插入相同的条目。
On this image entry 1 and 2 are inserted from EF Core while entry 3 was inserted from PHP
从图像中可以看出,数据库看起来很好,因为 PHP 的插入工作正常。
如何确保 EF Core 在添加条目时使用“utf8mb4”编码?
最佳答案
正如 Thomas Schmidt 在 OP 评论中所建议的那样,问题出在其他地方,我没有想到 Visual Studio 保存文件所用的编码。关于这个问题的解决方案是这样描述的:
razor view » character rendered as »
解决方案:
选择您要更改编码的文件,然后点击文件菜单,然后将“页面”另存为,然后选择Save with Encoding...并选择所需的编码。
我编辑了帖子的问题标题以反射(reflect)当前问题。让我知道是否应该将其改回来,因为我不确定如何继续。
关于c# - 将特殊字符分配给字符串时,Razor 页面会弄乱编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56955235/