I want to have a field for adding extra custom Key-Value data, that is rarely present. I see some do this with a Json string:
Example:
class Thingy1 {
[Key(0)] public int Id {get;}
// ... omitted fields ...
[Key(7)] public string ExtraJsonData {get;}
}
I could do this with an inner messagepack array too:
class Thingy2 {
[Key(0)] public int Id {get;}
// ... omitted fields ...
[Key(7)] public byte[] ExtraMsgPackData {get;}
}
so in this example, if ExtraMsgPackData is non-null (quite rare), then it would be deserialized as String-Key and examined.
What do you think? Is there a preferred way to do this?
byte[]
for you, or are you imagining that the serialized form of Thingy2
literally has one property called ExtraMsgPackData
that is set to a byte[]
value?
NetworkStream
, it fails. I'm assuming I am not reading the info from the stream properly. Is this approach flawed or has anything that could lead to the data being scrambled or not thread-safe?//_netStream: Network stream that is being read from only in this thread
//tokenSource: CancellationTokenSource from this class
while (server.Clients.Contains(this))
{
if (_netStream.DataAvailable)
using (var streamReader = new MessagePackStreamReader(_netStream))
{
try
{
ReadOnlySequence<byte> sequence = (ReadOnlySequence<byte>)await streamReader.ReadAsync(tokenSource.Token);
ServerPack obj = MessagePackSerializer.Deserialize<ServerPack>(sequence, PlayerdomGame.SerializerSettings, tokenSource.Token);
HandleMessage(obj);
}
catch(MessagePackSerializationException e)
{
}
}
else Task.Delay(10).Wait();
}
Hi, is it possible to deserialize to a different type than the one that was serialized? I have a service that is serializing IEnumerable<MyType> where MyType is:
struct MyType {
public DateTime Date {get; set;}
public int Value {get; set;}
}
But I eventually want a pair of IEnumerable<DateTime>, IEnumerable<int>, without having to materialize the List<MyType> before splitting. Perhaps a callback api on deserialization?
Thanks, Matt
Typeless
, the types themselves are not serialized, so you're free to deserialize them into any type you want. However the schema of what is serialized will resemble the original type if you're using one of the built-in formatters. So in msgpack you'd have an array of maps where each map has two entries (one for each property). There's no way you can deserialize that as two arrays of simple values each. You'll have to either deserialize the original schema first, or write low-level code to write or read the foreign schema into the object graph you want. For example, you might write a formatter and resolver that will serialize MyType[]
into a DateTime[]
and Value[]
in msgpack form. You wouldn't necessarily have to create these two arrays in the managed heap, but you'd have to use the MessagePackWriter
to write it out that way. Or you could bridge the schema difference in the deserialization side using MessagePackReader
.
Here is the class I am attempting to serialize.
[MessagePackObject]
public class RequestPacket<T>
{
[Key(0)]
public bool IsRequest { get; set; }
[Key(1)]
public Dictionary<T, byte[]> Messages { get; set; }
}
I am just using MessagePackSerializer.Serialize([The packet]);
System.TypeLoadException
Type 'MessagePack.Formatters.Small_Shared_Networking_RequestPacket`1\[\[Small_Tests_Networking_RequestTypes\, Small_Tests\]\]Formatter4' from assembly 'MessagePack.Resolvers.DynamicObjectResolver, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' is attempting to implement an inaccessible interface.
at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()
at System.Reflection.Emit.TypeBuilder.CreateTypeInfo()
at MessagePack.Internal.DynamicObjectTypeBuilder.BuildType(DynamicAssembly assembly, Type type, Boolean forceStringKey, Boolean contractless)
at MessagePack.Resolvers.DynamicObjectResolver.FormatterCache`1..cctor()
Fail in console app running on MessagepackCompiler.RunAsync
System.IndexOutOfRangeException: Index was outside the bounds of the array.
at System.Collections.Immutable.ImmutableArray`1.get_Item(Int32 index)
at MessagePackCompiler.CodeAnalysis.TypeCollector.<>c.<CollectUnion>b__20_2(ImmutableArray`1 x)
at System.Linq.Enumerable.SelectArrayIterator`2.ToArray()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.OrderedEnumerable`1.ToArray()
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at MessagePackCompiler.CodeAnalysis.TypeCollector.CollectUnion(INamedTypeSymbol type)
at MessagePackCompiler.CodeAnalysis.TypeCollector.CollectCore(ITypeSymbol typeSymbol)
at MessagePackCompiler.CodeAnalysis.TypeCollector.Collect()
at MessagePackCompiler.CodeGenerator.GenerateFileAsync(String input, String output, String conditionalSymbol, String resolverName, String namespace, Boolean useMapMode, String multipleIfDirectiveOutputSymbols)
at MessagePack.Generator.MessagepackCompiler.RunAsync(String input, String output, String conditionalSymbol, String resolverName, String namespace, Boolean useMapMode, String multipleIfDirectiveOutputSymbols)
at ConsoleAppFramework.ConsoleAppEngine.RunCore(ConsoleAppContext ctx, Type type, MethodInfo methodInfo, String[] args, Int32 argsOffset)
mpc
are you using and how did you install it? What does dotnet --info
tell you just after you see this error?