gpt4 book ai didi

docker - 如何从单独的 Docker 容器中调用 ASP.NET Core Web API 端点

转载 作者:行者123 更新时间:2023-12-05 03:45:38 25 4
gpt4 key购买 nike

我有两个项目:

  1. UI(.NET Core 3.1 MVC 字体端)
  2. API(.NET Core 3.1 Web API)

每个都在两个单独的容器中运行。他们共享一个构建它们的 docker-compose 文件。在 UI 项目中,我希望能够进行 AJAX 调用以命中 API 项目中的端点。 将到达我的端点的 URL 是什么?

我尝试过的:

  1. 如果我单独使用 IIS 运行 API 项目,我可以通过导航到 https://localhost:49239/weatherforecast 成功到达终点。但是,再次强调,我想通过从 UI 项目中的客户端调用它来达到这个端点。
  2. 如果我使用 docker-compose 启动两个容器,那么从 UI 项目中单击执行我对端点的 AJAX 调用的按钮 https://localhost:49239/weatherforecast 它不会工作。我已尝试对 URL 的主机部分进行多种变体来访问它。

根据 Networking in Compose

Compose sets up a single network for your app. Each container for aservice joins the default network and is both reachable by othercontainers on that network and is discoverable by them at a hostnameidentical to the container name.

为此,我还尝试了多种主机 URL 变体,例如 https://api:49243/weatherforecast,其中“api”是我的 docker 镜像的名称,“49243”是docker ps 列出的端口。我也试过:

  • https://api:80/weatherforecast
  • https://api:433/weatherforecast
  • https://api:PORT_NUM/weatherforecast 其中“PORT_NUM”是使用 docker ps
  • 查看时为容器列出的任何端口号

那么我该如何到达这个端点呢???

注意:

  • 我运行了 docker inspect CONTAINER_NAME,我知道这两个容器都在同一个网络上。

文件:

  1. UI > Index.cshtml:
@{
ViewData["Title"] = "Home Page";
}

<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://learn.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
<button type="button" class="btn btn-primary" onclick="callAPI()">Call API</button>
</div>

@section scripts {
<script>
function callAPI() {
console.log("calling API...");

$.ajax({
url: `https://api:49221/weatherforast/get`,
method: 'GET',
success: function (data) {
console.log(data);
},
error: function (error) {
console.log(error);
}
});
}
</script>
}
  1. 用户界面> Dockerfile:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["UI/UI.csproj", "UI/"]
RUN dotnet restore "UI/UI.csproj"
COPY . .
WORKDIR "/src/UI"
RUN dotnet build "UI.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "UI.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "UI.dll"]
  1. API > WeatherForecastController.cs:
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace API.Controllers
{
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

private readonly ILogger<WeatherForecastController> _logger;

public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}

[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}
}
  1. API > Dockerfile:
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["API/API.csproj", "API/"]
RUN dotnet restore "API/API.csproj"
COPY . .
WORKDIR "/src/API"
RUN dotnet build "API.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "API.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "API.dll"]
  1. docker-compose:
version: '3.4'

services:
ui:
image: ${DOCKER_REGISTRY-}ui
build:
context: .
dockerfile: UI/Dockerfile

api:
image: ${DOCKER_REGISTRY-}api
build:
context: .
dockerfile: API/Dockerfile
  1. 为了更好地理解解决方案结构,这是我的 Solution Explorer 的屏幕截图

最佳答案

最终我发现 Visual Studio 创建了一个我暂时没有注意到的文件,名为 docker-compose.override.yml。该文件在未指定主机端口的情况下公开了端口 80 和 443,我相信这是导致我的应用程序每次运行时都以随机端口号运行的原因。这让我很难知道将我的 API 调用指向何处。

本质上,只需将端口添加到我的 docker-compose.yml(如下面的代码块所示)并且(重要的是)从 docker-compose.override.yml 我能够让 UI 和 WebAPI 应用程序分别在指定端口上运行。从那里,我需要将主机名 “https://localhost:49254” 添加到我的 WebAPI 应用程序中的 CORS 策略,这样它就不会阻止来 self 的 UI 应用程序的请求。

version: '3.4'

services:
ui:
container_name: ui_container
image: ${DOCKER_REGISTRY-}ui
build:
context: .
dockerfile: UI/Dockerfile
ports:
- "49254:443"
api:
container_name: api_container
image: ${DOCKER_REGISTRY-}api
build:
context: .
dockerfile: API/Dockerfile
ports:
- "49255:443"

因此,要访问我的 API 端点,我必须使用 ajax 访问 https://localhost:49255/WeatherForecast

要查看我的所有代码,请查看我的 GitHub repository .

显然,如果我要将此应用程序投入生产,我需要调整主机名。

如果有人知道更好/更清洁的解决方案,请提出建议。

关于docker - 如何从单独的 Docker 容器中调用 ASP.NET Core Web API 端点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65673220/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com