如圖,該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,本地硬盤都可以。