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

如何解决C# API向SQL Server插入PDF后文件损坏问题

问题:C# API插入SQL Server的PDF文件损坏,打开提示格式错误

我开发了一个C# API用于读取并向SQL Server表插入PDF文件,前端使用React应用调用该API执行CRUD操作,React端运行正常无报错。

已通过以下SQL语句成功插入PDF文件,且能正常打开读取:

INSERT INTO [DEFLEGOPINION] (content,extension,title)
SELECT BulkColumn , '.pdf' , 'Title123'
FROM OPENROWSET(BULK N'C:\temp\test.pdf', SINGLE_BLOB) AS BulkColumn
SELECT CAST('string' as varbinary(max)) FOR XML PATH(''), BINARY BASE64

但通过C# API插入的PDF文件虽插入成功,打开时提示格式损坏。我的C# API插入代码如下:

connection.Open();
string[] newContent = content.Split(',');
//here I removed the 'data:application/pdf;base64' part since I read somewhere that this makes a problem and should be remove

string encodedStr = Convert.ToBase64String(Encoding.UTF8.GetBytes(content));

String sql = "INSERT INTO myTable(Id,Name,Content) values('" + Guid.NewGuid() + "', '"
+ name + "', CONVERT(varbinary(max), '" + newContent[1] + "', 0))";

using (SqlCommand command = new SqlCommand(sql, connection))
{
  command.ExecuteNonQuery();
  return true;
}
//Note:Name and Content are string parameters

React端读取其他文件正常,排除前端问题。想请教问题出在哪?是要修改C#端方法,还是采用基于文件路径的插入方式(但用户文件路径是动态未知的)?


问题根源分析

  • Base64处理逻辑错误:你拆分content拿到了正确的Base64部分newContent[1],但后续多余的Convert.ToBase64String(Encoding.UTF8.GetBytes(content))完全是错误操作——这相当于对Base64字符串再次编码,而且实际插入时直接把Base64字符串用CONVERT转varbinary,这会把Base64当成普通字符串转二进制,而非解码得到PDF原始字节。
  • SQL字符串拼接风险:直接将参数拼入SQL语句,不仅存在SQL注入风险,还可能因特殊字符导致二进制数据转换异常,破坏文件完整性。
  • 二进制转换方式错误:SQL中的CONVERT(varbinary(max), '', 0)是把字符串按默认编码转二进制,不是解码Base64,无法得到正确的PDF字节。

解决方案:修改C#端插入逻辑

不需要采用文件路径插入方式,直接正确处理前端传来的Base64数据,并用参数化SQL保证数据完整性,修改后的代码如下:

connection.Open();
string[] newContent = content.Split(',');
// 直接解码Base64字符串得到PDF原始字节数组
byte[] pdfBytes = Convert.FromBase64String(newContent[1]);

// 使用参数化SQL,避免注入和数据损坏
string sql = "INSERT INTO myTable(Id, Name, Content) VALUES (@Id, @Name, @Content)";

using (SqlCommand command = new SqlCommand(sql, connection))
{
    command.Parameters.AddWithValue("@Id", Guid.NewGuid());
    command.Parameters.AddWithValue("@Name", name);
    // 指定参数类型为VarBinary,确保二进制数据正确传递
    command.Parameters.Add("@Content", SqlDbType.VarBinary, -1).Value = pdfBytes;
    
    command.ExecuteNonQuery();
    return true;
}

为什么这样有效

  • Convert.FromBase64String(newContent[1])直接将前端传来的Base64字符串解码为PDF的原始二进制字节,这是存入数据库的正确数据。
  • 参数化SQL会直接把字节数组传递给SQL Server,无需额外转换,避免了字符串拼接带来的编码错误。
  • 完全支持动态用户文件,不需要依赖本地文件路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 19:05:15