MySqlDataReader.GetStream() 抛出 IndexOutOfRangeException [英] MySqlDataReader.GetStream() throws IndexOutOfRangeException

查看:44
本文介绍了MySqlDataReader.GetStream() 抛出 IndexOutOfRangeException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So I'm using the MySql.Data package for my .NET Core project and store password hashes and salts (of type byte[]) as varbinary() to the database. When selecting the password hash and salt from a user I need a way to convert the result back to a byte array. Given this sample code

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(Exception ex) 在MySql.Data.MySqlClient.MySqlDataReader.Throw(Exception ex) 在MySql.Data.MySqlClient.MySqlDataReader.GetBytes(Int32 i, Int64fieldOffset, Byte[] buffer, Int32 bufferoffset, Int32 length) atSystem.Data.Common.DbDataReader.GetStream(Int32 ordinal) 在Infrastructure.Persistence.Repositories.UsersRepository.<>c.<b__1_0>d.MoveNext()在/.../Infrastructure/Persistence/Repositories/UsersRepository.cs:line60

System.IndexOutOfRangeException: Data index must be a valid index in the field at MySql.Data.MySqlClient.Interceptors.ExceptionInterceptor.Throw(Exception exception) at MySql.Data.MySqlClient.MySqlConnection.Throw(Exception ex) at MySql.Data.MySqlClient.MySqlDataReader.Throw(Exception ex) at MySql.Data.MySqlClient.MySqlDataReader.GetBytes(Int32 i, Int64 fieldOffset, Byte[] buffer, Int32 bufferoffset, Int32 length) at System.Data.Common.DbDataReader.GetStream(Int32 ordinal) at Infrastructure.Persistence.Repositories.UsersRepository.<>c.<b__1_0>d.MoveNext() in /.../Infrastructure/Persistence/Repositories/UsersRepository.cs:line 60

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

although the reader contains the correct database results as you can see here down below (password is 32 bytes, hash is 16 bytes)

该错误是在2018年报告的

The error was reported in 2018

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

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

and has a verified status. Are there any good solutions / workarounds on how to solve it? I don't want to use the GetBytes method because it requires me to pass in the length of the byte array and I would like to stay independent from that.

推荐答案

卸载 MySql.Data 并替换为 MySqlConnector.

Uninstall MySql.Data and replace it with MySqlConnector.

(披露:我是您发现的 MySql 错误的报告者MySqlConnector 的主要贡献者.)

(Disclosure: I'm the reporter of the MySql bug you found and the primary contributor to MySqlConnector.)

以及修复该问题以及许多其他错误,MySqlConnector 添加了真正的异步 I/O 支持和性能改进.

As well as fixing that issue and many other bugs, MySqlConnector adds true async I/O support and performance improvements.

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

I don't want to use the GetBytes method because it requires me to pass in the length of the byte array and I would like to stay independent from that.

如果你不想切换库,GetBytes 的一个鲜为人知的特性(MySql.Data 和 MySqlConnector 都支持)是传入一个 null缓冲区返回所需的长度,因此您无需对其进行硬编码:

If you don't want to switch libraries, a little-known feature of GetBytes (supported by both MySql.Data and MySqlConnector) is that passing in a null buffer returns the needed length, so you don't need to hard-code it:

// 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);

这篇关于MySqlDataReader.GetStream() 抛出 IndexOutOfRangeException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆