Tja*_*tte 5 c# sql-server docker asp.net-core asp.net-core-webapi
在收集结合 docker 编写 .NET Core Web API 的知识时,我遇到了一个无法解决的错误。我已经在互联网上进行了研究,但不知何故,所提供的解决方案都不适合我。
我有一个名为的 Web 服务Catalog.API(类似于 Microsoft 的 eShopOnContainers 项目),其中有一个名为 的控制器CatalogController。
这是来自控制器的代码:
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Catalog.API.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Catalog.API.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class CatalogController : ControllerBase
{
private readonly CatalogItemContext _context;
public CatalogController(CatalogItemContext context)
{
_context = context;
}
public async Task<List<CatalogItem>> GetItemsAsync()
{
var items = await _context.CatalogItems.Where(model => model.Id < 10).ToListAsync();
return items;
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我只有一种方法应该从外部数据库返回 id 小于 10 的所有项目。
数据库添加在Startup.cs:
namespace Catalog.API
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<CatalogItemContext>(builder =>
{
builder.UseSqlServer(Configuration.GetConnectionString("Default"));
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseMvc();
}
}
}
Run Code Online (Sandbox Code Playgroud)
看起来appsettings.json像这样:
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"Default": "Server=localhost,1433;Initial Catalog=Test.Services.CatalogDb;User Id=sa;Password=Pass@word"
}
}
Run Code Online (Sandbox Code Playgroud)
为了构建此 Web 服务,我创建了一个从以下位置调用的 docker 文件docker-compose.yml:
FROM mcr.microsoft.com/dotnet/core/aspnet:2.2 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build
WORKDIR /src
COPY src/Services/Catalog/Catalog.API/Catalog.API.csproj /src/csproj-files/
WORKDIR ./csproj-files
RUN dotnet restore
WORKDIR /src
COPY . .
WORKDIR /src/src/Services/Catalog/Catalog.API/
RUN dotnet publish -c Release -o /app
FROM build AS publish
FROM base as final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "Catalog.API.dll"]
Run Code Online (Sandbox Code Playgroud)
看起来docker-compose.yml像这样:
version: '3.4'
services:
sqldata:
ports:
- 1433:1433
image: mcr.microsoft.com/mssql/server:2017-latest-ubuntu
environment:
- ACCEPT_EULA=Y
- SA_PASSWORD=Pass@word
catalog.api:
ports:
- 80:80
build:
context: .
dockerfile: src/Services/Catalog/Catalog.API/Dockerfile
depends_on:
- sqldata
Run Code Online (Sandbox Code Playgroud)
如前所述,除了 Catalog.API Web 服务之外,我还在 Docker 容器内运行 SQL Server 数据库。localhost出于开发目的,我使用 localhost 或我的计算机 IP 作为主机地址(或)从 DataGrip 连接到此 SQL Server 192.168.2.101。两种方法都工作正常,我可以毫无问题地在 DataGrip 内部建立连接。
我的问题是我无法从在CatalogControllerlocalhost:80 上运行的 docker 容器内部连接到 SQL Server。通常,当我调用 时localhost:80/api/catalog,我应该从数据库中获取所有项目(请参阅开头的控制器),但不知何故,我收到此错误:
失败:Microsoft.EntityFrameworkCore.Database.Connection[20004]
使用服务器“localhost,1433”上的数据库“Test.Services.CatalogDb”的连接时发生错误。
System.Data.SqlClient.SqlException (0x80131904): 建立与 SQL Server 的连接时发生网络相关或特定于实例的错误。服务器未找到或无法访问。验证实例名称是否正确以及 SQL Server 是否配置为允许远程连接。(提供程序:TCP 提供程序,错误:40 - 无法打开与 SQL Server 的连接)在System.Data.SqlClient.SqlInternalConnectionTds ..ctor(DbConnectionPoolIdentity标识,SqlConnectionString connectionOptions,SqlCredential凭据,对象providerInfo,字符串newPassword,SecureString newSecurePassword,布尔redirectedUserInstance,SqlConnectionString userConnectionOptions,SessionData reconnectSessionData,布尔applyTransientFaultHandling,字符串accessToken)在System.Data
。 SqlClient.SqlConnectionFactory.CreateConnection(DbConnectionOptions选项,DbConnectionPoolKey poolKey,对象poolGroupProviderInfo,DbConnectionPool池,DbConnection owningConnection,DbConnectionOptions userOptions)
在System.Data.ProviderBase.DbConnectionFactory.CreatePooledConnection(DbConnectionPool池,DbConnection owningObject,DbConnectionOptions选项,DbConnectionPoolKey池键、DbConnectionOptions userOptions)
在System.Data.ProviderBase.DbConnectionPool.CreateObject(DbConnection owningObject,DbConnectionOptions userOptions,DbConnectionInternal oldConnection)
在System.Data.ProviderBase.DbConnectionPool.UserCreateRequest(DbConnection owningObject,DbConnectionOptions userOptions,DbConnectionInternal oldConnection)
在System.Data.ProviderBase.DbConnectionPool.TryGetConnection (DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowedCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection)
at System.Data.ProviderBase.DbConnectionPool.WaitForPendingOpen()
--- 从抛出异常的上一个位置开始的堆栈跟踪结束 ---在 Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(布尔错误预期,CancellationToken取消令牌)ClientConnectionId:00000000-0000-0000-0000-000000000000
我已经尝试使用多个 ips(本地主机、我的机器 ip + docker 检查的 ip),但没有一个有效。
Server=192.168.2.101,1433;Initial Catalog=Test.Services.CatalogDb;User Id=sa;Password=Pass@word
Run Code Online (Sandbox Code Playgroud)
我愿意接受任何可以解决我的问题的帮助。提前致谢。
SQL Server 实例不在本地主机上。在 Web 应用程序的上下文中,localhost 是运行 Web 应用程序的容器,它与 SQL Server 所在的容器不同。
使用 Docker Compose 时,服务名称最终作为主机名,这意味着您可以简单地连接到sqldata,1433.
添加服务名称而不是 IP 是有效的,但是每当我使用“dotnet ef migrations add xyz”和“dotnet ef database update”迁移数据库时,我都会收到错误。它说,服务器未找到或无法访问。所以现在我可以连接,但无法使用 dotnet ef。
主机名仅在运行 docker 容器的 VLAN 内有效,该 VLAN 与桌面计算机所在的 VLAN 不同。要访问 SQL Server 容器,您必须docker container exec进入其中一个容器并从那里运行命令 (主机名将存在的位置sqldata)或者您必须使用容器的 IP 地址,您可以通过运行docker container ls获取容器 id (guid) 然后运行 来获取该 IP 地址docker inspect {container id}。IP 地址将位于NetworkSettings生成的 JSON 部分中。
| 归档时间: |
|
| 查看次数: |
5678 次 |
| 最近记录: |