先说结论:用 System.Drawing 在 .NET 6+ 的跨平台项目里生成验证码图片,这条路基本走不通。要么开启兼容模式,要么直接换成 SkiaSharp。如果是传统的 .NET Framework 4.x 项目,用 Graphics + Bitmap 没什么问题,但要注意字体嵌入和抗锯齿带来的干扰。

这篇文章会把报错原因、跨平台替换方案、以及 ASP.NET Core 中的安全绑定逻辑一次讲清楚。开始之前,先交代一个关键判断:真正麻烦的从来不是画图本身,而是如何在“防机器识别”和“不折磨真实用户”之间找到平衡。

为什么 System.Drawing 在 .NET Core / .NET 5+ 中无法正常工作?

最常见的翻车姿势是 System.PlatformNotSupportedException: System.Drawing.Common is not supported on this platform。从 .NET Core 3.0 开始,微软明确将 System.Drawing 标记为仅 Windows 平台兼容的库,Linux 和 macOS 上的容器或跨平台部署场景默认禁用 GDI+。这个坑几乎每个从 .NET Framework 迁移过来的开发者都踩过。

解决办法不是加个包就完事了——必须显式声明兼容性。在 .csproj 中添加以下配置:


    true

但要注意,这个方案只对 Windows 部署场景有效。如果用 Docker 跑应用,哪怕基础镜像选的是 mcr.microsoft.com/dotnet/aspnet:6.0-windowsservercore,还得确认 GDI+ 组件是否安装到位。相比之下,更稳妥的做法是直接切换到 SkiaSharp——它不依赖系统图形栈,跨平台兼容性好,而且能轻松实现中文、旋转、噪点这些进阶需求。

用 SkiaSharp 生成带干扰线和倾斜字符的验证码图

核心流程不复杂:创建 SKSurface -> 获取 SKCanvas -> 逐字符绘制(带随机角度) -> 加噪点 -> 输出 PNG 流。但在细节处有几个容易翻车的点,值得单独拎出来说:

下面是一个生成4字符验证码的关键代码片段:

using (var surface = SKSurface.Create(new SKImageInfo(120, 40)))
{
    var canvas = surface.Canvas;
    canvas.Clear(SKColors.White);
    var typeface = SKTypeface.FromFile("simhei.ttf");
    var paint = new SKPaint { Typeface = typeface, TextSize = 24 };
    
    string code = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
    var chars = Enumerable.Range(0, 4).Select(_ => code[new Random().Next(code.Length)]).ToArray();
    
    for (int i = 0; i < chars.Length; i++)
    {
        paint.Color = new SKColor((byte)new Random().Next(50, 150),
                                   (byte)new Random().Next(50, 150),
                                   (byte)new Random().Next(50, 150));
        canvas.DrawText(chars[i].ToString(), 20 + i * 25, 30 + (float)(Math.Sin(i * 0.5) * 5), paint);
    }
    
    var img = surface.Snapshot();
    var data = img.Encode(SKEncodedImageFormat.Png, 100);
    return File(data.ToArray(), "image/png");
}

ASP.NET Core 中如何安全返回验证码并绑定 Session?

验证码值绝对不能放在客户端(比如 hidden field),必须在服务端存储并与当前请求上下文强绑定。不少开发者写进 HttpContext.Session.SetString 后就忽略了过期和并发问题,这是典型的安全漏洞。

以下几点是必须做到的:

坦率说,真正考验产品能力的地方不在于画图,而在于平衡。噪点撒过头,移动端截图识别率直接暴跌;字间距窄得亲爹都看不清,视力不佳的用户直接放弃。这些都不是靠几行模板代码能解决的,必须根据具体业务场景的用户反馈反复调优。没有银弹,只有迭代。

本文转载于:https://www.php.cn/faq/2334314.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。