在Azure App Service中连接到In App MySQL时出现套接字错误

时间:2019-09-18 16:12:13

标签: mysql asp.net azure asp.net-core

我已将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。

1 个答案:

答案 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

为了将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) );
});

现在应该可以工作了。

演示

enter image description here