如何解决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
相关产品推荐
相关产品推荐

