从 .Net Core 3.1 升级到 .Net 5 后序列化和 MD5 哈希失败
Serialization and MD5 hashes failing after upgrading from .Net Core 3.1 to .Net 5
将我的一个应用程序从 .Net Core 3.1 升级到 .Net 5 后,我注意到处理字节数组序列化和 MD5 哈希的代码部分出现奇怪的故障。
该代码在 .Net Core 3.1 中工作得很好,但是在升级到 .Net 5 之后,当 运行 在 Linux 上时,我在运行时看到问题。
具体来说,代码将对象散列为 GUID,如下所示:
public Guid GenerateKey(string id, DateTime date1, DateTime? date2, string environment, string currencyCode, string ns, Dictionary<string, string> buildVersions)
{
var buildVersionString = string.Join(',', buildVersions.OrderBy(bv => bv.Key).Select(bv => $"{bv.Key}:{bv.Value}"));
var key = new Key(id, date1, date2, environment, currencyCode, ns, buildVersionString);
var str = JsonConvert.SerializeObject(key);
var bytes = Encoding.UTF8.GetBytes(str);
var hashBytes = ComputeHash(bytes);
return new Guid(hashBytes);
}
private byte[] ComputeHash(byte[] bytes)
{
using(var md5Hasher = MD5.Create())
{
return md5Hasher.ComputeHash(bytes);
}
}
在 .Net 3.1 中,我能够使用简单的 ToDictionary 调用生成多个 Guid:
var storedContents = new Content();
storedContents.Keys = request.Ids.ToDictionary(
k => k,
v => keyProvider.GenerateKey(
v,
request.Date1,
request.Date2,
request.Environment,
request.CurrencyCode,
request.Namespace,
request.BuildVersions)
);
但在 .Net 5 中,这开始失败并出现以下错误。奇怪的是它不会一直失败,但在发出一些请求后会非常可靠地失败。
Entry point was not found.
at System.Collections.Generic.IEnumerable`1.GetEnumerator()
at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source, Int32& length)
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.OrderedEnumerable`1.GetEnumerator()+MoveNext()
at System.Linq.Enumerable.SelectIPartitionIterator`2.MoveNext()
at System.String.JoinCore[T](Char* separator, Int32 separatorLength, IEnumerable`1 values)
at POC.KeyProvider.GenerateKey(String id, DateTime date1, Nullable`1 date2, String environment, String currencyCode, String ns, Dictionary`2 buildVersions) in /home/tor/development/bug-repro/Api/POC/KeyProvider.cs:line 27
at POC.StorageProvider.<>c__DisplayClass2_0.<GetContent>b__1(String v) in /home/tor/development/bug-repro/Api/POC/StorageProvider.cs:line 44
at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](TSource[] source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector)
at POC.StorageProvider.GetContent(MyRequest request) in /home/tor/development/bug-repro/Api/POC/StorageProvider.cs:line 42
at Api.Controllers.TestController.Get() in /home/tor/development/bug-repro/Api/Controllers/TestController.cs:line 44
at lambda_method7(Closure , Object , Object[] )
出于某种原因,我能够通过将 ToDictionary 转换为传统的 foreach 循环来让它工作。
storedContents.Keys = new Dictionary<string, System.Guid>();
foreach(var id in request.Ids)
{
var key = keyProvider.GenerateKey(
id,
request.Date1,
request.Date2,
request.Environment,
request.CurrencyCode,
request.Namespace,
request.BuildVersions
);
storedContents.Keys.Add(id, key);
}
这两个版本似乎都应该有效,并且在 .Net Core 3.1 中有效,但在 .Net 5 中,字典方法停止工作。关于为什么这会在 Linux 上的 .Net 5 中中断的任何想法? Windows 看起来不错,至少在我的本地开发机器上是这样。
我在这里重现了这个问题:https://github.com/thelgevold/Net5-Error
注意:在这个例子中,我使用的是 NewtonSoft 的 JsonConvert.SerializeObject。我在使用 MessagePack 进行序列化时遇到了同样的问题。
.Net 5.0.6 中已修复此问题。
将我的一个应用程序从 .Net Core 3.1 升级到 .Net 5 后,我注意到处理字节数组序列化和 MD5 哈希的代码部分出现奇怪的故障。
该代码在 .Net Core 3.1 中工作得很好,但是在升级到 .Net 5 之后,当 运行 在 Linux 上时,我在运行时看到问题。
具体来说,代码将对象散列为 GUID,如下所示:
public Guid GenerateKey(string id, DateTime date1, DateTime? date2, string environment, string currencyCode, string ns, Dictionary<string, string> buildVersions)
{
var buildVersionString = string.Join(',', buildVersions.OrderBy(bv => bv.Key).Select(bv => $"{bv.Key}:{bv.Value}"));
var key = new Key(id, date1, date2, environment, currencyCode, ns, buildVersionString);
var str = JsonConvert.SerializeObject(key);
var bytes = Encoding.UTF8.GetBytes(str);
var hashBytes = ComputeHash(bytes);
return new Guid(hashBytes);
}
private byte[] ComputeHash(byte[] bytes)
{
using(var md5Hasher = MD5.Create())
{
return md5Hasher.ComputeHash(bytes);
}
}
在 .Net 3.1 中,我能够使用简单的 ToDictionary 调用生成多个 Guid:
var storedContents = new Content();
storedContents.Keys = request.Ids.ToDictionary(
k => k,
v => keyProvider.GenerateKey(
v,
request.Date1,
request.Date2,
request.Environment,
request.CurrencyCode,
request.Namespace,
request.BuildVersions)
);
但在 .Net 5 中,这开始失败并出现以下错误。奇怪的是它不会一直失败,但在发出一些请求后会非常可靠地失败。
Entry point was not found.
at System.Collections.Generic.IEnumerable`1.GetEnumerator()
at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable`1 source, Int32& length)
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.OrderedEnumerable`1.GetEnumerator()+MoveNext()
at System.Linq.Enumerable.SelectIPartitionIterator`2.MoveNext()
at System.String.JoinCore[T](Char* separator, Int32 separatorLength, IEnumerable`1 values)
at POC.KeyProvider.GenerateKey(String id, DateTime date1, Nullable`1 date2, String environment, String currencyCode, String ns, Dictionary`2 buildVersions) in /home/tor/development/bug-repro/Api/POC/KeyProvider.cs:line 27
at POC.StorageProvider.<>c__DisplayClass2_0.<GetContent>b__1(String v) in /home/tor/development/bug-repro/Api/POC/StorageProvider.cs:line 44
at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](TSource[] source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)
at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector)
at POC.StorageProvider.GetContent(MyRequest request) in /home/tor/development/bug-repro/Api/POC/StorageProvider.cs:line 42
at Api.Controllers.TestController.Get() in /home/tor/development/bug-repro/Api/Controllers/TestController.cs:line 44
at lambda_method7(Closure , Object , Object[] )
出于某种原因,我能够通过将 ToDictionary 转换为传统的 foreach 循环来让它工作。
storedContents.Keys = new Dictionary<string, System.Guid>();
foreach(var id in request.Ids)
{
var key = keyProvider.GenerateKey(
id,
request.Date1,
request.Date2,
request.Environment,
request.CurrencyCode,
request.Namespace,
request.BuildVersions
);
storedContents.Keys.Add(id, key);
}
这两个版本似乎都应该有效,并且在 .Net Core 3.1 中有效,但在 .Net 5 中,字典方法停止工作。关于为什么这会在 Linux 上的 .Net 5 中中断的任何想法? Windows 看起来不错,至少在我的本地开发机器上是这样。
我在这里重现了这个问题:https://github.com/thelgevold/Net5-Error
注意:在这个例子中,我使用的是 NewtonSoft 的 JsonConvert.SerializeObject。我在使用 MessagePack 进行序列化时遇到了同样的问题。
.Net 5.0.6 中已修复此问题。