【问题标题】:How to use message pack in xamarin forms如何在 xamarin 表单中使用消息包
【发布时间】:2020-07-10 13:13:11
【问题描述】:

我必须使用MessagePack 来反序列化从 Web API (ASP.net) 返回的数据,这些数据是使用相同的包进行序列化的。

使用以下代码

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;
}

在调试模式下,在 Android 中一切正常,但在 iOS 中,调试和发布以及 Android 发布模式都运行良好。反序列化代码崩溃,出现以下异常

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 ---

在 MessagePack git 页面中找到了 section,指定了使用 Ahead of time 代码生成器解决此问题的方法。我按照这些步骤操作,但无法解决问题。我也确信我做得对。

如何在 Xamarin.Forms 中使用 MessagePack。任何已经建议我或提供参考的人都可以。

更新后的步骤

  1. 在单击按钮时使用了消息包序列化。
  2. 已安装 mpc 工具。
  3. 使用不要 mpc -i "{FormsProject.csproj path}" -o "{FormsProject directory path}"
  4. 将创建的消息包生成类添加到表单项目中。
  5. 在 App.xaml.cs Initialize 方法中使用了以下代码
StaticCompositeResolver.Instance.Register(
     MessagePack.Resolvers.GeneratedResolver.Instance,
     MessagePack.Resolvers.StandardResolver.Instance

现在也抛出(平台不支持操作)异常。我不太明白我在做什么。

更新 2:

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 

【问题讨论】:

  • 您没有使用使用mpc工具时生成的StaticCompositeResolver,您可能需要查看“AOT代码生成(支持Unity/Xamarin)的示例代码部分" 再次
  • 谢谢,我现在试试
  • @SushiHangover 尝试在我的项目中添加 StaticCompositeResolver 但不起作用(平台不支持操作)。所以创建了一个全新的解决方案,我已经按照我遵循的步骤更新了问题。我完全不明白(平台错误中不支持相同)。我正在使用mac机器。 Github 链接github.com/Nikhileshwar96/GitSamples.git.

标签: c# xamarin serialization deserialization msgpack


【解决方案1】:

需要将StaticCompositeResolver.Instance设置为默认值。
您缺少以下代码。

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

【讨论】:

  • 感谢您的回复。但即使在 MessagePackSerializerOptions 使用时也会引发错误。我已将异常添加到查询中。
  • 在消息包 nuget 包中解决了有关延迟加载默认解析器的问题。在 2.1.165 版本之后工作正常。 Git issue link 谢谢@neuecc。
【解决方案2】:

升级到MessagePack 2.1.165 或更高版本。

此问题已在版本 2.1.165 的消息包中修复。关于DynamicAssembly的懒加载。

Issue link

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-01
    • 2019-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多