Docker 运行 NET5 WebApi 出现 The type initializer for 'Gdip' threw an exception. 报错解决办法
如图,该webapi接口运行在Docker中,调用 /api/Verify/LoginVerifyCode接口时报错 The type initializer for 'Gdip' threw an exception.
后台看到是因为 libgdiplus这个类库找不到导致的!意思是在Docker容器里没有安装libgdiplus类库,只要安装上就可以了!
The type initializer for 'Gdip' threw an exception. System.TypeInitializationException: The type initializer for 'Gdip' threw an exception. ---> System.DllNotFoundException: Unable to load shared library 'libgdiplus' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: liblibgdiplus: cannot open shared object file: No such file or directory at System.Drawing.SafeNativeMethods.Gdip.GdiplusStartup(IntPtr& token, StartupInput& input, StartupOutput& output) at System.Drawing.SafeNativeMethods.Gdip..cctor() --- End of inner exception stack trace --- at System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromScan0(Int32 width, Int32 height, Int32 stride, Int32 format, IntPtr scan0, IntPtr& bitmap) at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format) at SkyebbBlogWebApi.Comm.Helper.VerifyCodeHelper.CreateImage(String code) in C:\Users\SkyEebb\Desktop\新建文件夹\skyebb-blog-webapi\SkyebbBlogWebApi.Comm\Helper\VerifyCodeHelper.cs:line 17 at SkyebbBlogWebApi.Controllers.VerifyController.GetUserLoginVerifyCode() in C:\Users\SkyEebb\Desktop\新建文件夹\skyebb-blog-webapi\SkyebbBlogWebApi\Controllers\VerifyController.cs:line 70 at lambda_method511(Closure , Object , Object[] ) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync() at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at System.Drawing.SafeNativeMethods.Gdip.GdipCreateBitmapFromScan0(Int32 width, Int32 height, Int32 stride, Int32 format, IntPtr scan0, IntPtr& bitmap) at System.Drawing.Bitmap..ctor(Int32 width, Int32 height, PixelFormat format) at SkyebbBlogWebApi.Comm.Helper.VerifyCodeHelper.CreateImage(String code) in C:\Users\SkyEebb\Desktop\新建文件夹\skyebb-blog-webapi\SkyebbBlogWebApi.Comm\Helper\VerifyCodeHelper.cs:line 17 at SkyebbBlogWebApi.Controllers.VerifyController.GetUserLoginVerifyCode() in C:\Users\SkyEebb\Desktop\新建文件夹\skyebb-blog-webapi\SkyebbBlogWebApi\Controllers\VerifyController.cs:line 70 at lambda_method511(Closure , Object , Object[] ) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync() at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextExceptionFilterAsync>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
接下来开始安装libgdiplus,执行【docker ps -a 】查看所有容器
【docker start 容器ID】 将容器运行起来
【docker exec -it e90f2b9d448d /bin/bash】进入该容器bash界面
执行【apt-get update】
【apt-get install -y libgdiplus】安装libgdiplus类库
【eixt】退出docker bash到宿主机的bash,执行 【docker restart 容器ID】,此时接口已经能正确访问了
上面的方法有个弊端,假如容器被误删,又要重新给容器安装libgdiplus库。
我们可以把修改好的容器制作成镜像,执行【docker commit e90f2b9d448d skyapi_libgdiplus】,然后执行【docker images】,
可以看到名字叫skyapi_libgdiplus的Docker镜像已经制作好了。今后只需要在 docker run -t 参数后面指定 skyapi_libgdiplus镜像即可。
当前还可以将镜像保存到docker hub,本地硬盘都可以。