无法从 Docker (Linux) 中运行的 ASP.NET Core 连接到 SQL Server 命名实例

Nor*_*n78 5 c# sql-server docker asp.net-core

我有一个应用程序应该使用命名实例连接到在远程服务器上运行的 SQL Server。

使用 IISExpress,我可以连接到 SQL Server,但从 Docker(Linux 容器)连接失败 - 访问上下文时它只是挂起 - 没有抛出异常或错误消息。例如

var context = serviceScope.ServiceProvider.GetService<AppContext>();
context.Users.ToList();
Run Code Online (Sandbox Code Playgroud)

在调试器中它永远不会到达异常处理程序。

相反,我看到很多这样的输出:

The thread 125 has exited with code 0 (0x0).
The thread 164 has exited with code 0 (0x0).
The thread 0xa4 has exited with code 0 (0x0).
Run Code Online (Sandbox Code Playgroud)

使用node.js,我什至可以从docker连接到SQL Server,没有问题。

当我使用例如 [ipaddress 或 host.docker.internal],1433 时,我可以从 Docker 中的 ASP.NET Core 连接到与 Docker 运行在同一台计算机上的 SQL Server Developer 版本 - 不幸的是,在远程 SQL Server 上,我无法配置固定端口。

  • 使用 IISExpress 工作(因此在 Windows 上运行)
  • 当使用固定端口而不是命名实例连接到在开发计算机上运行的 SQL Server 时有效(但我无法更改我们的生产服务器)
  • 使用 Node.js 时有效!来自 docker 也带有命名实例(两者:带有主机名或 IP 地址 - 所以我可以解析远程名称,防火墙不是问题)
  • 尝试使用 Microsoft 容器作为基础的 ASP.NET Core 2.2 和 3.0preview5,例如 FROM mcr.microsoft.com/dotnet/core/aspnet:3.0-buster-slim AS 基础

连接字符串:

"Data Source=remoteIP\\WEBDB;Initial Catalog=TestDB;User ID=testuser;Password=******;"
Run Code Online (Sandbox Code Playgroud)

还尝试过“Integrated Security=False;” 在连接字符串中

服务器身份验证设置为混合

我也可以在没有实体框架的情况下重现这一点:

var conString = "Data Source=remoteIP\\WEBDB;Initial Catalog=TestDB;Integrated Security=False;User ID=testuser;Password=********";

using (SqlConnection conn = new SqlConnection(conString))
using (SqlCommand cmd = new SqlCommand("SELECT * FROM Users", conn))
{
   conn.Open();
   var rows = cmd.ExecuteNonQuery();
   Console.WriteLine($"rows: {rows}");
}
Run Code Online (Sandbox Code Playgroud)

它会挂在网上conn.Open();

知道我能做什么吗?

更新:

  • 输入的连接字符串不正确。
  • 更新了代码并包含完整的示例

编辑

这有效:

var conString = "Data Source=10.0.75.1,1433;Initial Catalog=TestDB;Integrated Security=False;User ID=testuser;Password=********";
Run Code Online (Sandbox Code Playgroud)

这不起作用:

var conString = "Data Source=10.0.75.1\\Developer;Initial Catalog=TestDB;Integrated Security=False;User ID=testuser;Password=********";
Run Code Online (Sandbox Code Playgroud)

我可以 ping 远程 IP 地址以及远程服务器名称。

不幸的是,由于缺少依赖项,在 ubuntu 映像上安装 mssql-cli 失败。

Pan*_*vos 0

Data Source是错误的。命名实例仅使用一个反斜杠。正确的来源是:

remoteIP\WEBDB
Run Code Online (Sandbox Code Playgroud)

仅当字符串存储在需要转义的介质(例如 C# 字符串或 JSON 字符串)中时,才需要转义反斜杠。对于 C#、JSON、Javascript 和 C++ 相关语言,转义字符是反斜杠本身,例如:

var connectionString="Data Source=remoteIP\\WEBDB;Initial Catalog=TestDB;User ID=testuser;Password=******;"
Run Code Online (Sandbox Code Playgroud)

或者

{
    "ConnectionStrings": {
        "BloggingDatabase": "Server=(localdb)\\mssqllocaldb;Database=EFGetStarted.ConsoleApp.NewDb;Trusted_Connection=True;"
    },
}
Run Code Online (Sandbox Code Playgroud)

文字 C# 字符串、XML 或 INI 文件不需要转义。以下 C# 行不需要转义。

var connectionString=@"Data Source=remoteIP\WEBDB;Initial Catalog=TestDB;User ID=testuser;Password=******;"
Run Code Online (Sandbox Code Playgroud)

编辑

修复名称只是可能出错的一件事。当 DNS 尝试将无法识别的字符串解析为有效的 IP 时,错误的地址很容易让应用程序崩溃。

另一个问题是 Docker 容器默认没有网络连接。您必须指定它们可以连接到的内容以及内部 IP 和端口如何映射到外部 IP 和端口。

您可以使用 SQL Server CLI 工具mssql-cli来测试与服务器的连接,而无需运行自己的应用程序:

mssql-cli -S InternallyMappedIP\WEBDB -d TestDB -U testuser
Run Code Online (Sandbox Code Playgroud)