Orleans IPercientState POCO 命名空间版本控制问题

问题描述 投票:0回答:1

我正在使用

 <PackageReference Include="Microsoft.Orleans.Sdk" Version="8.2.0" />
为非常简单的记录生成序列化器:

 namespace BaseNamespace.OldNameSpace;
 [GenerateSerializer, Alias("MyRecord")]
 public sealed record MyRecord
 {
    [Id(0)]
    public string Name{ get; set; }
    [Id(1)]
    public int Age { get; set; }
 }

我有一个带有以下构造函数的谷物:

public sealed class MyRecordGrain([PersistentState(stateName: "MyRecordValue", MyRecordStorageKey")] IPersistentState<MyRecord> state) : IGrain, IMyRecordGrain

每次调用 Grain 时,我都会设法存储该对象并通过构造函数检索它。在 SQL Server 中,使用 select cast(PayloadBinary as varchar(MAX)), * from OrleansStorage

PayloadBinary
列上看起来像这样:

{
    "$id": "1",
    "$type": "BaseNamespace.OldNameSpace.MyRecord, MyProject.Common.Model",
    "Name": "Anthony",
    "Age ": 14,
},

当我大量重构类库命名空间时,问题就出现了。如果我将

MyRecord
的命名空间从
namespace BaseNamespace.OldNameSpace;
更改为
namespace BaseNamespace.NewNameSpace;
并调用grain,则存储序列化将失败并出现此错误,因为命名空间不匹配:

    Error from storage provider AdoNetGrainStorage.personCache during ReadStateAsync for grain personCache/PersonCacheKey
 
Exc level 0: Newtonsoft.Json.JsonSerializationException: Error resolving type specified in JSON 'BaseNamespace.OldNameSpace.MyRecord,  MyProject.Common.Model], System.Collections.Concurrent'. Path '$type', line 1, position 263.
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ResolveTypeName(JsonReader reader, Type& objectType, JsonContract& contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, String qualifiedTypeName)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadMetadataProperties(JsonReader reader, Type& objectType, JsonContract& contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue, Object& newValue, String& id)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)
   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)

如果我将命名空间改回

BaseNamespace.OldNameSpace
一切正常。我知道我应该向记录类添加
alias
以便它们支持不同的版本,但是如何避免此命名空间重构错误?如果我已经在grain的构造函数中提供了有关程序集和命名空间的信息,为什么序列化数据需要存储这些信息
IPersistentState<MyRecord>

谢谢!

c# .net orleans
1个回答
0
投票

已回答https://github.com/dotnet/orleans/discussions/9085

必须将 JsonSerializer 配置调整为:

siloBuilder.Configure<OrleansJsonSerializerOptions>(options =>
{
    options.JsonSerializerSettings.TypeNameHandling = TypeNameHandling.Auto;
})
© www.soinside.com 2019 - 2024. All rights reserved.