如何在 xamarin 表单中使用消息包
How to use message pack in xamarin forms
我必须使用 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 指定使用提前代码生成器解决此问题的方法。我按照这些步骤操作,但无法解决问题。另外我确定我做对了。
如何在 Xamarin.Forms 中使用 MessagePack。有哪位已经推荐过或者提供参考的可以吗
更新后续步骤
- 在单击按钮时使用消息包序列化。
- 已安装 mpc 工具。
- 不用mpc -i "{FormsProject.csproj路径}" -o "{FormsProject目录路径}"
- 将生成的消息包 class 添加到表单项目中。
- 在App.xaml.cs
Initialize
方法中使用了以下代码
StaticCompositeResolver.Instance.Register(
MessagePack.Resolvers.GeneratedResolver.Instance,
MessagePack.Resolvers.StandardResolver.Instance
现在还抛出(平台不支持操作)异常。我不太明白我在做什么。
更新二:
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
需要将 StaticCompositeResolver.Instance
设置为默认值。
您缺少以下代码。
var option = MessagePackSerializerOptions.Standard.WithResolver(StaticCompositeResolver.Instance);
MessagePackSerializer.DefaultOptions = option;
升级到 MessagePack
2.1.165 或更高版本。
此问题已在版本 2.1.165 的消息包中修复。关于DynamicAssembly
.
的延迟加载
我必须使用 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 指定使用提前代码生成器解决此问题的方法。我按照这些步骤操作,但无法解决问题。另外我确定我做对了。
如何在 Xamarin.Forms 中使用 MessagePack。有哪位已经推荐过或者提供参考的可以吗
更新后续步骤
- 在单击按钮时使用消息包序列化。
- 已安装 mpc 工具。
- 不用mpc -i "{FormsProject.csproj路径}" -o "{FormsProject目录路径}"
- 将生成的消息包 class 添加到表单项目中。
- 在App.xaml.cs
Initialize
方法中使用了以下代码
StaticCompositeResolver.Instance.Register(
MessagePack.Resolvers.GeneratedResolver.Instance,
MessagePack.Resolvers.StandardResolver.Instance
现在还抛出(平台不支持操作)异常。我不太明白我在做什么。
更新二:
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
需要将 StaticCompositeResolver.Instance
设置为默认值。
您缺少以下代码。
var option = MessagePackSerializerOptions.Standard.WithResolver(StaticCompositeResolver.Instance);
MessagePackSerializer.DefaultOptions = option;
升级到 MessagePack
2.1.165 或更高版本。
此问题已在版本 2.1.165 的消息包中修复。关于DynamicAssembly
.