如何在 C# 中处理二维码错误信息

This article was translated from English: Does it need improvement?
Translated
View the article in English

IronQR 的错误处理功能可帮助您捕获读取和写入失败,记录诊断信息,并从每次扫描中获得清晰的结果。 如果不添加显式检查,无论是空结果还是损坏的文件都不会返回任何内容,因此您将不知道哪里出了问题。 通过添加有针对性的异常处理和诊断日志记录,您可以将静默故障转化为有用的反馈。 本指南解释了如何处理空结果、管理写入时异常以及为批量处理构建结构化日志包装器。

快速入门:处理二维码错误

将 QR 读取操作封装在 try-catch 块中,并记录文件和解码失败的诊断信息。

  1. 使用 NuGet 包管理器安装 https://www.nuget.org/packages/IronQR

    PM > Install-Package IronQR
  2. 复制并运行这段代码。

    using IronQr;
    using IronSoftware.Drawing;
    
    try
    {
        var input = new QrImageInput(AnyBitmap.FromFile("label.png"));
        var results = new QrReader().Read(input);
        Console.WriteLine($"Found {results.Count()} QR code(s)");
    }
    catch (IOException ex)
    {
        Console.Error.WriteLine($"File error: {ex.Message}");
    }
  3. 部署到您的生产环境中进行测试

    通过免费试用立即在您的项目中开始使用IronQR

    arrow pointer

处理读取错误和空结果

不记录日志,空结果和损坏的文件对调用者来说看起来是一样的。 以下示例检测文件访问失败,如果扫描未返回任何结果,则发出警告。

输入

此二维码示例输入已存在于磁盘上。 我们将模拟两种情况:一种是用户检索并解码文件,另一种是文件路径不正确。

有效的二维码输入编码 https://ironsoftware.com/qr/scan-1
:path=/static-assets/qr/content-code-examples/how-to/detailed-error-messages/read-diagnostics.cs
using IronQr;
using IronSoftware.Drawing;

string filePath = "damaged-scan.png";

try
{
    // File-level failure throws IOException or FileNotFoundException
    var inputBmp = AnyBitmap.FromFile(filePath);
    var imageInput = new QrImageInput(inputBmp);

    var reader = new QrReader();
    IEnumerable<QrResult> results = reader.Read(imageInput);

    if (!results.Any())
    {
        // Not an exception — but a diagnostic event worth logging
        Console.Error.WriteLine($"[WARN] No QR codes found in: {filePath}");
        Console.Error.WriteLine($"  Action: Verify image quality or try a different scan");
    }
    else
    {
        foreach (QrResult result in results)
        {
            Console.WriteLine($"[{result.QrType}] {result.Value}");
        }
    }
}
catch (FileNotFoundException)
{
    Console.Error.WriteLine($"[ERROR] File not found: {filePath}");
}
catch (IOException ex)
{
    Console.Error.WriteLine($"[ERROR] Cannot read file: {filePath} — {ex.Message}");
}
catch (Exception ex)
{
    Console.Error.WriteLine($"[ERROR] Unexpected failure reading {filePath}: {ex.GetType().Name} — {ex.Message}");
}
Imports IronQr
Imports IronSoftware.Drawing

Module Module1
    Sub Main()
        Dim filePath As String = "damaged-scan.png"

        Try
            ' File-level failure throws IOException or FileNotFoundException
            Dim inputBmp = AnyBitmap.FromFile(filePath)
            Dim imageInput = New QrImageInput(inputBmp)

            Dim reader = New QrReader()
            Dim results As IEnumerable(Of QrResult) = reader.Read(imageInput)

            If Not results.Any() Then
                ' Not an exception — but a diagnostic event worth logging
                Console.Error.WriteLine($"[WARN] No QR codes found in: {filePath}")
                Console.Error.WriteLine("  Action: Verify image quality or try a different scan")
            Else
                For Each result As QrResult In results
                    Console.WriteLine($"[{result.QrType}] {result.Value}")
                Next
            End If
        Catch ex As FileNotFoundException
            Console.Error.WriteLine($"[ERROR] File not found: {filePath}")
        Catch ex As IOException
            Console.Error.WriteLine($"[ERROR] Cannot read file: {filePath} — {ex.Message}")
        Catch ex As Exception
            Console.Error.WriteLine($"[ERROR] Unexpected failure reading {filePath}: {ex.GetType().Name} — {ex.Message}")
        End Try
    End Sub
End Module
$vbLabelText   $csharpLabel

输出

终端输出显示 [QRCode] https://ironsoftware.com/qr/scan-1,表示二维码读取成功

请注意成功读取时只会返回二维码值,而运行时出错则会显示如下所示的异常消息或警告。

下方的控制台显示,对于结果为空的情况会显示 [WARN],对于文件缺失的情况会显示 [ERROR],并分别附有文件路径和建议的操作。

终端输出显示警告信息:未在 damage-scan.png 中找到二维码;错误信息:未找到 missing-label.png 文件。

处理写入失败

null 传递给 QrWriter.Write 会触发 IronQrEncodingException。 超出配置纠错级别的数据容量也会抛出异常,因为更高的纠错级别会降低可用数据容量。

输入

以下两个输入变量定义了失败场景:nullContent 等于 null,而 oversizedContent 是一个 5,000 字符的字符串,其长度在最高纠错级别下已超出 QR 的容量。

:path=/static-assets/qr/content-code-examples/how-to/detailed-error-messages/write-diagnostics.cs
using IronQr;

string? content = null; // null throws IronQrEncodingException 
string oversizedContent = new string('A', 5000); // 5,000 chars exceeds QR capacity at Highest error correction level 

// Scenario 1: null input
try
{   
    QrCode qr = QrWriter.Write(content); // Input
}
catch (Exception ex)
{
    Console.Error.WriteLine($"[ERROR] Null content: {ex.GetType().Name} — {ex.Message}"); // Output
}

// Scenario 2: data exceeds QR capacity at the configured error correction level
try
{
    var options = new QrOptions(QrErrorCorrectionLevel.Highest);
    QrCode qr = QrWriter.Write(oversizedContent, options); // Input
}
catch (Exception ex)
{
    Console.Error.WriteLine($"[ERROR] QR capacity exceeded: {ex.Message}"); // Output
    Console.Error.WriteLine($"  Input length: {oversizedContent.Length} chars");
    Console.Error.WriteLine($"  Action: Reduce content or lower error correction level");
}
Imports IronQr

Dim content As String = Nothing ' Nothing throws IronQrEncodingException 
Dim oversizedContent As String = New String("A"c, 5000) ' 5,000 chars exceeds QR capacity at Highest error correction level 

' Scenario 1: null input
Try
    Dim qr As QrCode = QrWriter.Write(content) ' Input
Catch ex As Exception
    Console.Error.WriteLine($"[ERROR] Null content: {ex.GetType().Name} — {ex.Message}") ' Output
End Try

' Scenario 2: data exceeds QR capacity at the configured error correction level
Try
    Dim options As New QrOptions(QrErrorCorrectionLevel.Highest)
    Dim qr As QrCode = QrWriter.Write(oversizedContent, options) ' Input
Catch ex As Exception
    Console.Error.WriteLine($"[ERROR] QR capacity exceeded: {ex.Message}") ' Output
    Console.Error.WriteLine($"  Input length: {oversizedContent.Length} chars")
    Console.Error.WriteLine("  Action: Reduce content or lower error correction level")
End Try
$vbLabelText   $csharpLabel

输出

控制台会显示两种故障情况下的异常类型和消息。

终端输出显示 IronQrEncodingException 异常,原因是传递给 QrWriter.Write 的内容为空。

记录异常消息中的输入长度,以确定该问题是否需要更短的内容或更低的修正级别。 对于用户输入,在编码之前验证字符串长度并检查空值,以减少异常开销并改进诊断。


记录二维码操作

使用 IronSoftware.Logger 捕获内部诊断信息。 对于每个读取操作,实现一个辅助程序,以 JSON 格式记录文件路径、结果计数和经过时间,以确保整个批次的输出清晰明了。

输入

该批次包含来自 qr-scans/ 的四个有效 QR 图像,以及一个包含无效字节的第五个文件 scan-05-broken.png

QR code encoding https://ironsoftware.com/qr/scan-1
QR code encoding https://ironsoftware.com/qr/scan-2
QR code encoding https://ironsoftware.com/qr/scan-3
QR code encoding https://ironsoftware.com/qr/scan-4
:path=/static-assets/qr/content-code-examples/how-to/detailed-error-messages/logging-wrapper.cs
using IronQr;
using IronSoftware.Drawing;
using System.Diagnostics;

// Enable shared Iron Software logging for internal diagnostics
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;
IronSoftware.Logger.LogFilePath = "ironqr-debug.log";

// Reusable wrapper for structured observability
(IEnumerable<QrResult> Results, bool Success, string Error) ReadQrWithDiagnostics(string filePath)
{
    var sw = Stopwatch.StartNew();
    try
    {
        var input = new QrImageInput(AnyBitmap.FromFile(filePath));
        var results = new QrReader().Read(input).ToList();
        sw.Stop();

        Console.WriteLine($"{{\"op\":\"qr_read\",\"file\":\"{Path.GetFileName(filePath)}\","
            + $"\"status\":\"ok\",\"count\":{results.Count},\"ms\":{sw.ElapsedMilliseconds}}}");

        return (results, true, null);
    }
    catch (Exception ex)
    {
        sw.Stop();
        string error = $"{ex.GetType().Name}: {ex.Message}";

        Console.Error.WriteLine($"{{\"op\":\"qr_read\",\"file\":\"{Path.GetFileName(filePath)}\","
            + $"\"status\":\"error\",\"exception\":\"{ex.GetType().Name}\","
            + $"\"message\":\"{ex.Message}\",\"ms\":{sw.ElapsedMilliseconds}}}");

        return (Enumerable.Empty<QrResult>(), false, error);
    }
}

// Usage: process a batch with per-file isolation
string[] files = Directory.GetFiles("qr-scans/", "*.png");
int ok = 0, fail = 0;

foreach (string file in files)
{
    var (results, success, error) = ReadQrWithDiagnostics(file);
    if (success && results.Any()) ok++;
    else fail++;
}

Console.WriteLine($"\nBatch complete: {ok} success, {fail} failed/empty out of {files.Length} files");
Imports IronQr
Imports IronSoftware.Drawing
Imports System.Diagnostics
Imports System.IO
Imports System.Linq

' Enable shared Iron Software logging for internal diagnostics
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All
IronSoftware.Logger.LogFilePath = "ironqr-debug.log"

' Reusable wrapper for structured observability
Private Function ReadQrWithDiagnostics(ByVal filePath As String) As (IEnumerable(Of QrResult), Boolean, String)
    Dim sw = Stopwatch.StartNew()
    Try
        Dim input = New QrImageInput(AnyBitmap.FromFile(filePath))
        Dim results = New QrReader().Read(input).ToList()
        sw.Stop()

        Console.WriteLine($"{{""op"":""qr_read"",""file"":""{Path.GetFileName(filePath)}"",""status"":""ok"",""count"":{results.Count},""ms"":{sw.ElapsedMilliseconds}}}")

        Return (results, True, Nothing)
    Catch ex As Exception
        sw.Stop()
        Dim error As String = $"{ex.GetType().Name}: {ex.Message}"

        Console.Error.WriteLine($"{{""op"":""qr_read"",""file"":""{Path.GetFileName(filePath)}"",""status"":""error"",""exception"":""{ex.GetType().Name}"",""message"":""{ex.Message}"",""ms"":{sw.ElapsedMilliseconds}}}")

        Return (Enumerable.Empty(Of QrResult)(), False, error)
    End Try
End Function

' Usage: process a batch with per-file isolation
Dim files As String() = Directory.GetFiles("qr-scans/", "*.png")
Dim ok As Integer = 0, fail As Integer = 0

For Each file As String In files
    Dim result = ReadQrWithDiagnostics(file)
    Dim results = result.Item1
    Dim success = result.Item2
    Dim error = result.Item3

    If success AndAlso results.Any() Then
        ok += 1
    Else
        fail += 1
    End If
Next

Console.WriteLine($"\nBatch complete: {ok} success, {fail} failed/empty out of {files.Length} files")
$vbLabelText   $csharpLabel

输出

控制台显示每个文件的 JSON 日志行:四次成功读取和一条损坏文件的结构化错误条目,然后是批次摘要。 IronSoftware.Logger 会同时将内部诊断信息写入 IronQR-debug.log。您可以在此处下载完整的调试日志。

终端输出显示了 4 次成功读取和 1 次错误的 JSON 结构化日志行,Plus批处理完成摘要。

生成的 JSON 数据可直接输入日志聚合工具:在容器化部署环境中,通过管道 stdout 传输至 Fluentd、Datadog 或 CloudWatch。 ms 字段会显示延迟退化问题,而调试日志会捕获包装器未记录的内部处理步骤。


进一步阅读

-纠错级别:在编码级别调整 QR 码的容错能力。 -如何读取二维码:从头到尾的读取指南。 -二维码生成器教程:生成带样式和徽标的二维码。

准备投入生产时,请查看许可选项

点击这里下载完整的 DetailedErrorMessagesTest 控制台应用程序项目。

Curtis Chau
技术作家

Curtis Chau 拥有卡尔顿大学的计算机科学学士学位,专注于前端开发,精通 Node.js、TypeScript、JavaScript 和 React。他热衷于打造直观且美观的用户界面,喜欢使用现代框架并创建结构良好、视觉吸引力强的手册。

除了开发之外,Curtis 对物联网 (IoT) 有浓厚的兴趣,探索将硬件和软件集成的新方法。在空闲时间,他喜欢玩游戏和构建 Discord 机器人,将他对技术的热爱与创造力相结合。

准备开始了吗?
Nuget 下载 63,625 | 版本: 2026.4 刚刚发布
Still Scrolling Icon

还在滚动吗?

想快速获得证据? PM > Install-Package IronQR
运行示例 观看您的 URL 变成 QR 代码。