Nikhileshwar
Nikhileshwar

Reputation: 1684

How to use message pack in xamarin forms

I have to use MessagePack to deserialize data returned from a web API (ASP.net), which was Serialized using the same package.

Used the following code

public async static Task<T> DeserializeAsync<T>(Stream stream)
{
    if (stream == null)
    {
        throw new ArgumentNullException(nameof(stream), "Stream value cannot be null");
    }
     
    stream.Position = 0;
    T deserialized = await MessagePackSerializer.DeserializeAsync<T>(stream, MessagePack.Resolvers.ContractlessStandardResolver.Options).ConfigureAwait(false);
    return deserialized;
}

All was working fine in Android in debug mode but in iOS both debug and release and in Android release mode. The deserialization code crashed with the following exceptions

Android -> Release 

[MonoDroid]   at MessagePa07-10 18:06:01.269 I/MonoDroid(13495): MessagePack.MessagePackSerializationException: Failed to deserialize Project.Core.Models.SomeData Class value. ---> System.TypeInitializationException: The type initializer for 'FormatterCache`1' threw an exception. ---> MessagePack.Internal.MessagePackDynamicObjectResolverException: can't find public constructor. type:System.Drawing.Drawing2D.Matrix
[MonoDroid]   at MessagePack.Internal.ObjectSerializationInfo.CreateOrNull (System.Type type, System.Boolean forceStringKey, System.Boolean contractless, System.Boolean allowPrivate) [0x009a0] in <23c4c9b023514c20801c8f07fd69206c>:0 
[MonoDroid]   at MessagePack.Internal.DynamicObjectTypeBuilder.BuildType (MessagePack.Internal.DynamicAssembly assembly, System.Type type, System.Boolean forceStringKey, System.Boolean contractless) [0x00015] in <23c4c9b023514c20801c8f07fd69206c>:0 

iOS->
System.TypeInitializationException: The type initializer for 'Project.Core.Helpers.BinarySerializer' threw an exception. ---> System.TypeInitializationException: The type initializer for 'MessagePack.Resolvers.ContractlessStandardResolver' threw an exception. ---> System.TypeInitializationException: The type initializer for 'MessagePack.Internal.StandardResolverHelper' threw an exception. ---> System.TypeInitializationException: The type initializer for 'MessagePack.Resolvers.DynamicEnumResolver' threw an exception. ---> System.PlatformNotSupportedException: Operation is not supported on this platform.
  at MessagePack.Internal.DynamicAssembly..ctor (System.String moduleName) [0x0001a] in <f04e2061de5c414991b8e36a20354820>:0 
  at MessagePack.Resolvers.DynamicEnumResolver..cctor () [0x00010] in <f04e2061de5c414991b8e36a20354820>:0 
   --- End of inner exception stack trace ---
  at (wrapper managed-to-native) System.Object.__icall_wrapper_mono_generic_class_init(intptr)
  at MessagePack.Internal.StandardResolverHelper..cctor () [0x00000] in <f04e2061de5c414991b8e36a20354820>:0 
   --- End of inner exception stack trace ---

Found the section in the MessagePack git page specifying a way to overcome this issue using an Ahead of time code generator. I followed the steps but was not able to fix the issue. Also I'm sure I'm doing it right.

How do I use MessagePack in Xamarin.Forms. Can anyone who has already suggest me or provide a reference.

Update on steps followed

  1. Used message pack serialization in a button click.
  2. Installed mpc tool.
  3. Used don't mpc -i "{FormsProject.csproj path}" -o "{FormsProject directory path}"
  4. Added the created message pack generated class to the forms project.
  5. Used the following code in App.xaml.cs Initialize method
StaticCompositeResolver.Instance.Register(
     MessagePack.Resolvers.GeneratedResolver.Instance,
     MessagePack.Resolvers.StandardResolver.Instance

Now also the (Operation is not supported in the platform) Exception is thrown. I'm not quite getting what I'm doing wring here.

Update 2:

Exception in the MessagePackSerializerOptions

System.TypeInitializationException: The type initializer for 'MessagePackSerializerOptionsDefaultSettingsLazyInitializationHelper' threw an exception. ---> System.TypeInitializationException: The type initializer for 'MessagePack.Resolvers.StandardResolver' threw an exception. ---> System.TypeInitializationException: The type initializer for 'MessagePack.Internal.StandardResolverHelper' threw an exception. ---> System.TypeInitializationException: The type initializer for 'MessagePack.Resolvers.DynamicEnumResolver' threw an exception. ---> System.PlatformNotSupportedException: Operation is not supported on this platform.
  at System.Reflection.Emit.AssemblyBuilder.DefineDynamicAssembly (System.Reflection.AssemblyName name, System.Reflection.Emit.AssemblyBuilderAccess access) [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/src/Xamarin.iOS/mcs/class/corlib/System.Reflection.Emit/AssemblyBuilder.pns.cs:129 
  at MessagePack.Internal.DynamicAssembly..ctor (System.String moduleName) [0x0001a] in <f04e2061de5c414991b8e36a20354820>:0 
  at MessagePack.Resolvers.DynamicEnumResolver..cctor () [0x00010] in <f04e2061de5c414991b8e36a20354820>:0 

Upvotes: 2

Views: 1811

Answers (2)

Nikhileshwar
Nikhileshwar

Reputation: 1684

Upgrade to version of MessagePack 2.1.165 or higher.

This issue was fixed in Message pack in version 2.1.165. Regarding the lazy loading of DynamicAssembly.

Issue link

Upvotes: 0

neuecc
neuecc

Reputation: 48

Require to set StaticCompositeResolver.Instance as default.
You lacks following code.

var option = MessagePackSerializerOptions.Standard.WithResolver(StaticCompositeResolver.Instance);
MessagePackSerializer.DefaultOptions = option;

Upvotes: 1

Related Questions