Dotnet 核心 2.2 libgdipplus 异常

Dotnet core 2.2 libgdipplus exception

我是 运行 openshift 上的 dotnet core 2.2 web api,我有一个 api 方法,return 是一个 FileResult。该文件是使用 epplus 生成的。但是,在将应用程序容器化后,端点 return 出现以下错误。我相信如果使用 system.drawing 库会发生此异常,但是我没有使用任何 system.drawing 功能。

System.TypeInitializationException: The type initializer for 'Gdip' threw an exception. ---> System.DllNotFoundException: Unable to load DLL 'libgdiplus': The specified module could not be found.

public async Task<FileResult> GetPSACostCaseAndFeedData([FromQuery] int caseId, [FromQuery] int proposalId, [FromQuery] int equipmentId)
        {
            try
            {
                var queryParams = new Dictionary<string, string> { { "caseId", caseId.ToString() }, { "proposalId", proposalId.ToString() }, { "equipmentId", equipmentId.ToString() } };
                var restObj = _restFactory.createRestRequest(Method.GET, "ProposalService/PSACostData/GetPSACostCaseAndFeedData", queryParams);
                Console.WriteLine("Base URL - "  + restObj.Item2.BaseUrl);
                var response = await restObj.Item2.ExecuteTaskAsync(restObj.Item1);
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    var result = JsonConvert.DeserializeObject<PSACostCaseDetailsResponse>(response.Content);
                    Console.WriteLine("result -" + response.Content.ToString());
                    Console.WriteLine("start writing file");
                    var excelPackage = await _iPSACostExcelHelper.PopulatePsaCostFile(result, Path.Combine(_hostingEnvironment.ContentRootPath, "App_data", "PSACOST_V9.2.2.xlsm"));
                    Console.WriteLine("finished writing file");
                    return await Task.FromResult(File(_excelHelper.ConvertWorkBookToByteArray(excelPackage), ContentTypeEnums.excel, result.customerInformationModel.ProposalNum + "_" + result.caseDataModel.CaseNm + ".xlsm"));
                }
                throw new Exception("There is no PSA cost data for this case");
            }

行 "finished writing file" 确实打印到标准输出,之后的行失败。有人可以帮我了解这里出了什么问题吗?为什么 return FileResult 类型的方法需要 system.drawing?

下面还有我的dockerfile。

FROM mcr.microsoft.com/dotnet/core/aspnet:2.2.7-alpine3.10
LABEL pipelineName="PSACOST.API" \
      pipelineKey="UMAOKJOH" \
      offeringKey="KKWEECBH"
RUN apk upgrade -U
EXPOSE 5000
ENV ASPNETCORE_URLS=http://*:5000
WORKDIR /app
COPY . /app
USER guest
ENTRYPOINT ["dotnet", "PSACOST.API.Web.dll"] 

我在使用生成 QR 码的库中的 System.Drawing 时遇到了类似的问题。

问题似乎是 DotNet Core docker 图像、sdk 或运行时没有 libgdiplus。 这对 Linux 来说不是问题,因为您可以在您的容器中执行类似 apt-get install -y libgdiplus 的操作,或者使用 DotNetCore 运行时映像加上此 libgdiplus.[= 构建您的应用程序 docker 映像24=]

这是个烦人的问题。我不确定是否有任何解决方案不需要弄乱官方 docker 图片,但到目前为止运气不好。

目前我可以看到一些解决方案。

选项A: 如果您正在为 linux 使用 docker DotNetCore 图像,看起来,请使用 apt 安装缺少的运行时依赖项,例如 libgdiplus,因为它们不是 docker 图像的一部分.

选项 B: 找到一个好的 docker DotNetCore 图像(sdk 或运行时),所有这些依赖就位

选项 C: 查找除 epplus 之外的不依赖于 System.Drawinglibgdiplus 的其他库。但我什至不知道这是否可能


更新 1 对于选项 B,您可以尝试使用以下包含 aspnet core runtime + 所需依赖项的 docker 图像: lonwern/aspnetcore-libgdiplus:2.1

如果您选择选项 A,有关如何生成图像的更多信息,请在此处查看图像的创建方式: https://hub.docker.com/r/lonwern/aspnetcore-libgdiplus/dockerfile


更新 2 我创建了 public Docker 图像,其中包含 DotNet Core SDK 和 AspNet Core 以及 libgdiplus,以便在 运行 应用程序使用 System.Drawing 使用 SDK DotNet Core CLI(例如:dotnet vstest、dotnet test 等)或使用运行时。

https://hub.docker.com/repository/docker/sunnyatticsoftware/dotnet-core-sdk-libgdiplus

https://hub.docker.com/repository/docker/sunnyatticsoftware/dotnet-core-aspnet-libgdiplus

有关存储库本身的更多信息。

我在我的 CI/CD 管道和网络应用程序的最终 Docker 图像中使用它们来避免这些运行时异常。