我已将ASP.NET Core 2.2 Web API应用程序部署到Azure App Service。我将In App MySQL作为应用程序服务的一部分。调用API时,出现以下错误:
ALLOWED_HOSTS = ['*']
我环顾四周,找到一个解决方案:Access denied error while connecting to MySQL in App in Azure App Service
但是上面建议的修复不能解决问题。
我还尝试了各种连接字符串,所有这些字符串都导致相同的异常。这是我目前所拥有的:
"ExtendedSocketException: An attempt was made to access a socket in a way forbidden by its access permissions 127.0.0.1:3306"
所以,我的问题是:如何使ASP.NET Core API连接到我的 In App MySql数据库?
PS1:有很多文章描述了如何解决Azure MySql DB的连接问题(例如设置防火墙访问等),而不是In App MySQL。
答案 0 :(得分:1)
首先,您无法通过appsettings.json
配置连接字符串。通过环境变量: MYSQLCONNSTR_localdb
自动配置Azure InApp MySQL连接字符串。
根据the docs:
Configuration API对于四个为应用程序环境配置Azure连接字符串所涉及的连接字符串环境变量具有特殊的处理规则。如果没有为AddEnvironmentVariables提供前缀,则将具有表中所示前缀的环境变量加载到应用程序中。
简而言之,您需要通过以下方式获得预定义的ConnectionString
:
var conn = Configuration.GetConnectionString("localdb");
此外,Azure InApp MySQL ConnectionString
不是 Standard MySQL ConnectionString
:
Database=localdb;Server={host_like_127.0.0.1}:{port_like_52841};Uid={azure};Pwd={random}
换句话说,默认的ConnectionString
还不能在C#中使用。
为了将InApp MySQL与ASP.NET Core
连接,我们需要对其进行规范化,然后再将其传递给UseMySQL(conn)
。这是我的脏代码,用于规范默认的InApp ConnectionString:
private string NormalizeAzureInAppConnString(string raw) {
string conn = string.Empty;
try
{
var dict =
raw.Split(';')
.Where(kvp => kvp.Contains('='))
.Select(kvp => kvp.Split(new char[] { '=' }, 2))
.ToDictionary(kvp => kvp[0].Trim(), kvp => kvp[1].Trim(), StringComparer.InvariantCultureIgnoreCase);
var ds = dict["Data Source"];
var dsa = ds.Split(":");
conn = $"Server={dsa[0]};Port={dsa[1]};Database={dict["Database"]};Uid={dict["User Id"]};Pwd={dict["Password"]};";
}
catch {
throw new Exception("unexpected connection string: datasource is empty or null");
}
return conn;
}
然后您可以按如下所示注册DbContext:
services.AddDbContext<AppDbContext>(options =>{
var conn = Configuration.GetConnectionString("localdb");
options.UseMySql( NormalizeAzureInAppConnString(conn) );
});
现在应该可以工作了。