将Azure SQL中Blob文件转Base64时遇类型转换异常问题
问题解决:System.InvalidCastException: 无法将String类型转换为Byte[]
问题根源
触发异常的核心原因是:代码中读取的DocumentTitle字段在Azure SQL表中是字符串类型(如VARCHAR/ NVARCHAR),但你试图直接将其强转为byte[]类型,类型不匹配导致转换失败。此外代码存在SQL注入风险,且可能你选错了存储Blob二进制内容的字段。
修复步骤
1. 确认SQL表字段类型与查询字段
先检查DocMeta表:
- 存储Blob二进制内容的字段必须是二进制类型(如
VARBINARY(MAX)),而非字符串类型。 - 确保你查询的是存储Blob内容的字段,而非
DocumentTitle这类字符串字段(比如字段名可能是DocumentContent)。
2. 替换为参数化SQL查询(避免注入)
原代码用字符串拼接生成SQL语句,存在严重的SQL注入风险,必须改为参数化查询:
string query = "SELECT DocumentContent FROM DocMeta WHERE DocumentID = @Id"; using(SqlCommand command = new SqlCommand(query, connection)) { // 添加参数,避免SQL注入 command.Parameters.Add(new SqlParameter("@Id", id)); using(SqlDataReader reader = await command.ExecuteReaderAsync()) { // 后续读取逻辑 } }
3. 正确读取二进制数据
如果字段是VARBINARY(MAX)类型,有两种稳妥的读取方式:
方式1:直接强转(适用于小数据)
if(await reader.ReadAsync()) { byte[] fileData = (byte[])reader["DocumentContent"]; string base64String = Convert.ToBase64String(fileData); // 构造响应 }
方式2:使用GetBytes(适用于大二进制数据)
if(await reader.ReadAsync()) { int ordinal = reader.GetOrdinal("DocumentContent"); long byteCount = reader.GetBytes(ordinal, 0, null, 0, 0); byte[] fileData = new byte[byteCount]; reader.GetBytes(ordinal, 0, fileData, 0, (int)byteCount); string base64String = Convert.ToBase64String(fileData); // 构造响应 }
4. 若确实需将字符串转为Base64
如果你误操作,实际需要将DocumentTitle字符串转为Base64,需先将字符串按指定编码转为字节数组:
if(await reader.ReadAsync()) { string title = reader.GetString(reader.GetOrdinal("DocumentTitle")); // 选择合适的编码,比如UTF-8 byte[] fileData = Encoding.UTF8.GetBytes(title); string base64String = Convert.ToBase64String(fileData); // 构造响应 }
完整修复后的代码片段
// ... 其他代码不变 ... using(SqlConnection connection = new SqlConnection(connectionString)) { await connection.OpenAsync(); // 改用参数化查询,且查询正确的二进制字段 string query = "SELECT DocumentContent FROM DocMeta WHERE DocumentID = @Id"; using(SqlCommand command = new SqlCommand(query,connection)) { command.Parameters.Add(new SqlParameter("@Id", id)); using(SqlDataReader reader = await command.ExecuteReaderAsync()) { if(await reader.ReadAsync()) { // 读取二进制数据 int ordinal = reader.GetOrdinal("DocumentContent"); long byteCount = reader.GetBytes(ordinal, 0, null, 0, 0); byte[] fileData = new byte[byteCount]; reader.GetBytes(ordinal, 0, fileData, 0, (int)byteCount); string base64String = Convert.ToBase64String(fileData); var response = new { id = id, content = base64String }; return new OkObjectResult(response); } else { return new NotFoundObjectResult($"Document with DocumentID '{id}' not found."); } } } } // ... 其他代码不变 ...
内容的提问来源于stack exchange,提问作者Gopikrishna Karanam
相关产品推荐
相关产品推荐

