当链接器设置为全部链接时,JSON 反序列化失败
Posted
技术标签:
【中文标题】当链接器设置为全部链接时,JSON 反序列化失败【英文标题】:JSON Deserialize fails when linker is set to Link All 【发布时间】:2016-10-01 09:40:09 【问题描述】:尝试在设备上反序列化 JSON 时出现 ArgumentNullException。这是确切的错误:
这里是调用代码:
private TMetadata ReadObject(string path)
var data = File.ReadAllText(path);
var obj = JsonConvert.DeserializeObject(data, _settings);
return (TMetadata) obj;
我通读了this thread 并意识到这是一个链接器问题。我的项目在构建到设备时设置为全部链接,由于尺寸限制,将其更改为不链接是不可行的。
我检查了 json 文本并找到了它试图反序列化的类型,然后转到该类并将其标记为 Preserve(AllMembers = true)]。我将相同的属性添加到该类中正在使用的任何用户定义的类。但是,我仍然遇到同样的错误。我还将 --linkskip=AssemblyName 添加到其他 mtouch 参数中,但没有运气。
有人有什么建议吗?至少有什么方法可以从 xamarin 获得一些更有用的信息吗?当异常发生时,它会将我带到一个看似随机的行 - 一个不相关类中的事件声明 - 并且单击堆栈中的方法什么都不做。我不知道“方法”参数是什么。
这是在 ReadObject 调用之后开始的堆栈:
Newtonsoft.Json.Utilities.ValidationUtils.ArgumentNotNull(object value, string parameterName) in
Newtonsoft.Json.Utilities.ExpressionReflectionDelegateFactory.CreateParametrizedConstructor(System.Reflection.MethodBase method) in
Newtonsoft.Json.Serialization.JsonArrayContract.CreateWrapper(System.Collections.Generic.Dictionary<Bluebeam.Studio.Client.SDK.Sessions.SessionMarkupId,Bluebeam.Studio.Client.SDK.Sessions.ServerState.Pending.PendingItems.PendingMarkupDto> list) in
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateNewList(Newtonsoft.Json.JsonTextReader reader, Newtonsoft.Json.Serialization.JsonArrayContract contract, bool createdFromNonDefaultCreator) in
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(Newtonsoft.Json.JsonTextReader reader, System.MonoType objectType, Newtonsoft.Json.Serialization.JsonArrayContract contract, Newtonsoft.Json.Serialization.JsonProperty member, object existingValue, string id) in
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(Newtonsoft.Json.JsonTextReader reader, System.MonoType objectType, Newtonsoft.Json.Serialization.JsonArrayContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonObjectContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, object existingValue) in
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(Newtonsoft.Json.Serialization.JsonProperty property, Newtonsoft.Json.JsonConverter propertyConverter, Newtonsoft.Json.Serialization.JsonObjectContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerProperty, Newtonsoft.Json.JsonTextReader reader, Bluebeam.Studio.Client.SDK.Sessions.ServerState.Pending.PendingItems.PendingMarkupsData target) in
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Bluebeam.Studio.Client.SDK.Sessions.ServerState.Pending.PendingItems.PendingMarkupsData newObject, Newtonsoft.Json.JsonTextReader reader, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, string id) in
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(Newtonsoft.Json.JsonTextReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, object existingValue) in
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(Newtonsoft.Json.JsonTextReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, object existingValue) in
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(Newtonsoft.Json.JsonTextReader reader, System.Type objectType, bool checkAdditionalContent) in
Newtonsoft.Json.JsonSerializer.DeserializeInternal(Newtonsoft.Json.JsonTextReader reader, System.Type objectType) in
Newtonsoft.Json.JsonSerializer.Deserialize(Newtonsoft.Json.JsonTextReader reader, System.Type objectType) in
Newtonsoft.Json.JsonConvert.DeserializeObject(string value, System.Type type, Newtonsoft.Json.JsonSerializerSettings settings) in
Newtonsoft.Json.JsonConvert.DeserializeObject(string value, Newtonsoft.Json.JsonSerializerSettings settings) in
【问题讨论】:
“全部链接”总是让人头疼,因为发布包的默认行为不是“全部链接”而是“仅链接 SDK 程序集”,这应该足以减小包大小.如果将其设置为“仅链接 SDK 程序集”,是否会引发异常? 当我将它设置为“仅链接 SDK 程序集”时它可以正常工作,但它会为应用程序大小增加 40mb,我们真的不想这样做,因为我们正在尝试获取它小于 100mb,因此可以通过蜂窝网络下载。 我也遇到过类似的问题,但设置 linkskip 参数对我有用。这是在android还是ios上?每个链接器的配置都不同。 只有链接 sdk 的 apk 多 40Mb?哇,很多,您可能正在使用很多外部库...我认为问题不在于您的课程,而是在 Json 库上,链接时似乎失去了一些功能,请尝试添加到链接器选项“--linkskip=NameOfAssemblyToSkipWithoutFileExtension”,首先尝试使用 json 库,如果它不起作用,请尝试使用您可能正在使用的其他库。 @Gusman "--linkskip=Newtonsoft.Json" 修复了它。谢谢! 【参考方案1】:解决方案是在附加的 mtouch 参数中添加“--linkskip=Newtonsoft.Json”。感谢Gusman 的建议!
【讨论】:
以上是关于当链接器设置为全部链接时,JSON 反序列化失败的主要内容,如果未能解决你的问题,请参考以下文章
Spring boot 动态/注解自定义 JSON 反序列化器