【问题标题】:MySqlDataReader.GetStream() throws IndexOutOfRangeExceptionMySqlDataReader.GetStream() 抛出 IndexOutOfRangeException
【发布时间】:2020-11-01 01:28:39
【问题描述】:

所以我将 MySql.Data 包用于我的 .NET Core 项目,并将密码哈希和盐(byte[] 类型)作为varbinary() 存储到数据库中。从用户那里选择密码哈希和盐时,我需要一种将结果转换回字节数组的方法。鉴于此示例代码

Stream passwordHashStream = dbDataReader.GetStream(0);
byte[] passwordHash;
                        
using (MemoryStream memoryStream = new MemoryStream())
{
    await passwordHashStream.CopyToAsync(memoryStream);
    passwordHash = memoryStream.ToArray();
}

第一行会抛出这个异常

System.IndexOutOfRangeException:数据索引必须是有效的索引 场在 MySql.Data.MySqlClient.Interceptors.ExceptionInterceptor.Throw(异常 例外)在 MySql.Data.MySqlClient.MySqlConnection.Throw(异常前)在 MySql.Data.MySqlClient.MySqlDataReader.Throw(Exception ex) 在 MySql.Data.MySqlClient.MySqlDataReader.GetBytes(Int32 i, Int64 fieldOffset, Byte[] buffer, Int32 bufferoffset, Int32 length) at System.Data.Common.DbDataReader.GetStream(Int32 序数)在 Infrastructure.Persistence.Repositories.UsersRepository.c.d.MoveNext() 在 /.../Infrastructure/Persistence/Repositories/UsersRepository.cs:line 60

尽管阅读器包含正确的数据库结果,如下所示(密码为 32 字节,哈希为 16 字节)

2018年报错

https://bugs.mysql.com/bug.php?id=93374

并且具有已验证的状态。是否有任何好的解决方案/解决方法来解决它?我不想使用GetBytes 方法,因为它需要我传递字节数组的长度,我想保持独立。

【问题讨论】:

  • GetItem(0) 转换为 byte[] 有效吗?
  • 对不起,这个方法不存在。 dbDataReader.GetItem(0)
  • 我的错误命名空间

标签: c# mysql mysql.data


【解决方案1】:

卸载 MySql.Data 并将其替换为MySqlConnector

(披露:我是MySql bug you found 的记者,也是MySqlConnector 的主要贡献者。)

除了修复该问题 and many other bugs,MySqlConnector 还添加了真正的异步 I/O 支持和性能改进。

我不想使用GetBytes 方法,因为它需要我传入字节数组的长度,而我想保持独立。

如果你不想切换库,GetBytes(MySql.Data 和 MySqlConnector 都支持)的一个鲜为人知的功能是传入null 缓冲区返回所需的长度,所以你不要'不需要硬编码:

// get the length of the column and allocate a buffer
var length = dbDataReader.GetBytes(0, 0, null, 0, 0);
var passwordHash = new byte[length];

// fill the buffer from the column
dbDataReader.GetBytes(0, 0, passwordHash, 0, passwordHash.Length);

【讨论】:

    【解决方案2】:

    public static async Task<MemoryStream> ToMemoryStream(this Stream stream)
        {
          var memStream = stream as MemoryStream;
          if (memStream == null)
          {
            memStream = new MemoryStream();
            await stream.CopyToAsync(memStream);
          }
          return memStream;
        }

    【讨论】:

    • 对不起,我不明白你的解决方案。能稍微解释一下吗?
    • Asy 函数应该从 asy 函数调用。我不知道你调用 CopyToAsync 的函数
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多