You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从SQL提取预格式化Base64到C#时的BOM编码问题排查

问题:从SQL Server提取Base64图片到Blazor Server时出现编码异常

我需要将SQL Server数据库中存储的Base64编码图片提取到Blazor Server(.NET 8)应用,嵌入到HTML的<a>标签内。此前提议更换图片存储方式,但数据团队明确表示无法修改现有存储逻辑。

数据库中存储Base64字符串的列类型为VARCHAR(MAX),当前核心问题出在Microsoft.Data.SqlClient查询后的编码处理环节:直接通过SQL查询得到的字符串能正常作为img元素的src属性渲染图片,但C#代码查询返回的字符串却无法解码。经解码工具检测发现,C#输出的字符串存在字节顺序标记(BOM),手动修复BOM后即可正常解码为图片。我推测这是C#默认UTF16编码导致的,但尝试多种方法均无法有效移除BOM并得到可用的图片字符串。

相关代码

string invoiceNumber = "INV12345";
string query = "SELECT invoiceImage FROM dbo.receipts WHERE invoiceNumber = @InvoiceNumber";

using (SqlConnection connection = new SqlConnection(connectionString))
{
    using (SqlCommand command = new SqlCommand(query, connection))
    {
        command.Parameters.AddWithValue("@InvoiceNumber", invoiceNumber);

        try
        {
            await connection.OpenAsync();

            var result = await command.ExecuteScalarAsync();

            if (result != null && result != DBNull.Value)
            {
                // 存在问题的字符串
                string EmbedImage = result.ToString();
                Console.WriteLine(EmbedImage);
            }
            else
            {
                Console.WriteLine("未找到对应发票号的图片");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("错误: " + ex.Message);
        }
    }
}

已尝试的方案

  1. 使用Convert.ToBase64String()方法(注:原代码存在编译错误,已修正为合理写法)
EmbedImage = Convert.ToBase64String(Encoding.UTF8.GetBytes(result.ToString()));
  1. 修剪BOM字符
EmbedImage = result.ToString().Trim(new char[]{'\uFEFF','\u200B'});
  1. 转换为字节数组再转回字符串
byte[] bytes = Convert.FromBase64String(result.ToString());
EmbedImage = Convert.ToBase64String(bytes);

解决方案

问题根源在于SQL Server的VARCHAR(MAX)列存储的是单字节编码的Base64字符串,而C#读取时可能因编码转换引入UTF-16 BOM或隐藏无效字符,以下是针对性解决方法:

1. 精准清理非Base64字符

Base64仅包含A-Za-z0-9+/=字符,直接用正则移除所有非合规字符,彻底清理BOM及其他无效内容:

string rawBase64 = result.ToString();
EmbedImage = Regex.Replace(rawBase64, @"[^A-Za-z0-9+/=]", string.Empty);

2. 按SQL默认编码读取字节数组

SQL Server的VARCHAR默认采用SQL_Latin1_General_CP1_CI_AS编码(对应Windows-1252),直接读取字节数组再转字符串,跳过可能出错的自动编码转换:

var resultBytes = await command.ExecuteScalarAsync() as byte[];
if (resultBytes != null)
{
    string rawBase64 = Encoding.GetEncoding(1252).GetString(resultBytes);
    // 额外清理残留的BOM和空字符
    EmbedImage = rawBase64.Trim(new char[] {'\uFEFF', '\u0000', '\u200B'});
}

3. 在SQL查询阶段直接清理BOM

如果C#端处理麻烦,可在SQL查询时直接移除开头的BOM前缀:

SELECT 
    CASE 
        WHEN LEFT(invoiceImage, 1) = NCHAR(65279) THEN SUBSTRING(invoiceImage, 2, LEN(invoiceImage))
        ELSE invoiceImage
    END AS invoiceImage
FROM dbo.receipts 
WHERE invoiceNumber = @InvoiceNumber

验证与使用

处理完成后,可将字符串复制到解码工具验证有效性,在Blazor中直接使用时需指定图片格式:

<img src="data:image/png;base64,@EmbedImage" alt="发票图片" />

(根据实际图片格式替换png为jpeg等)

内容的提问来源于stack exchange,提问作者Starship24

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 05:35:10