【问题标题】:Xamarin Forms - Serialization/Deserialization not workingXamarin Forms - 序列化/反序列化不起作用
【发布时间】:2020-10-16 06:43:54
【问题描述】:

预期行为:

在 Xamarin.Forms 项目 (MyApp) 中,我引用了一个带有自定义模型的类库 (Custom.Netcore.Models.dll),包含在单独的项目/单独的解决方案中。目标是将模型从我们的 API/数据库的 xml 文件序列化为 json,使用 Newtonsoft.Json 通过 MyApp 的 REST 检索和反序列化它们以填充 ViewModel 对象,通过 MyApp 的 UI 通过各种交互创建更改,然后将它们序列化并 POST 到自定义。 Netcore.API。

实际行为:

预期行为仅在通过 UWP 运行 MyApp 时起作用。当尝试通过 Android/iOS(模拟器)运行解决方案并且应用程序获取 REST 调用以填充 MyApp 的 ViewModels 时,应用程序通过

成功获取序列化数据

var data = await response.Content.ReadAsStringAsync();

然后当应用程序尝试解析数据并通过反序列化到模型时

ObservableCollection<Model> Records = JsonConvert.DeserializeObject<ObservableCollection<Model>>(data);

此时 Android/iOS 都给出相同的错误并导致应用程序停止运行:

安卓:

System.TypeLoadException: 'Could not resolve type with token 0100000c from typeref (expected class 'System.Xml.Serialization.XmlRootAttribute' in assembly 'System.Xml.ReaderWriter, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')'

iOS:

Failed to resolve "System.Void System.Xml.Serialization.XmlRootAttribute::.ctor()" reference from "System.Xml.ReaderWriter, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"

但是,我能够通过简单的方法在所有平台上成功创建和填充使用 Custom.Netcore.Models.Model 定义的 ViewModel 对象

ObservableCollection<Model> Records = new ObservableCollection<Model>()
{
    new Model(){ Id = 0, Description = "First Model", Type = "One"},
    new Model(){ Id = 1, Description = "Second Model", Type = "Two"}
};

日志:(Android)

Can't find custom attr constructor image: /storage/emulated/0/Android/data/com.companyname.MyApp/files/.__override__/Custom.Netcore.Models.dll mtoken: 0x0a000010 due to: Could not resolve type with token 0100000c from typeref (expected class 'System.Xml.Serialization.XmlRootAttribute' in assembly 'System.Xml.ReaderWriter, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') assembly:System.Xml.ReaderWriter, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a type:System.Xml.Serialization.XmlRootAttribute member:(null) **System.TypeLoadException:** 'Could not resolve type with token 0100000c from typeref (expected class 'System.Xml.Serialization.XmlRootAttribute' in assembly 'System.Xml.ReaderWriter, Version=4.2.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')'

设置:

Custom.Netcore.Api:

  • &lt;TargetFramework&gt;netcoreapp2.1&lt;/TargetFramework&gt;
  • Microsoft.AspNetCore.App - v2.1.1
  • Microsoft.NETCore.App - v2.1.0
  • NETStandard.Library - v.2.0.3
  • System.Configuration.ConfigurationManager - v5.0.0-preview.4.20251.6
  • System.Data.SqlClient - v4.8.1
  • System.Runtime - v4.3.1

XF.MyApp:

  • &lt;TargetFramework&gt;netstandard2.0&lt;/TargetFramework&gt;
  • Xamarin.Forms - v4.7.0.968
  • Newtonsoft.Json - v12.0.3
  • NETStandard.Library - v2.0.3

Custom.Netcore.Models.Model.cs:

namespace Custom.Netcore.Models
{
    [Serializable()]
    [System.Xml.Serialization.XmlRoot("Model")]
    public class Model
    {
        [System.Xml.Serialization.XmlAttribute("id")]
        public int Id { get; set; }
        [System.Xml.Serialization.XmlAttribute("description")]
        public string Description { get; set; }
        [System.Xml.Serialization.XmlElement("Type")]
        public string Type { get; set; }
    }
}

API 数据:

[
  {
    "id": 0,
    "description": "First Model",
    "type" = "One"
  },
  {
    "id": 1,
    "description": "Second Model",
    "type" = "Two"
  }
]

一周来一直在尝试解决此问题,因此我们将不胜感激!

【问题讨论】:

  • 为什么不直接使用 json?为什么要混合xml和json?
  • @Jason 这就是后端设置转换特定文件类型的方式,但是 API/XF 之间的所有内容都是 json 格式(我将编辑该部分以便更清晰)
  • @Jason xml 文件仅用于将数据获取到数据库/API,当应用程序与 api 通信时,其他所有内容都是 json
  • 如果你执行typeof(Model).GetCustomAttributes(true),模拟器上会发生什么?
  • 这就是 Newtonsoft 抛出的原因:一种基本的反射方法在模拟器上无法正常工作。在序列化过程中的某个时候,Newtonsoft 尝试获取 Model 的所有自定义属性,但失败并抛出所示异常——尽管特定属性是用于 XML 序列化的。显然,包含XmlRootAttribute 定义的 DLL 没有被链接,或者它被删除,因为它被认为是未使用的。我不是安卓开发者,所以我不能告诉你如何解决这个问题。

标签: serialization .net-core xamarin.forms json.net .net-standard-2.0


【解决方案1】:

日志和错误列表不会直接告诉您在 iOS 和 Android 上,由于我无法在网上找到类似的问题,我将把它留给将来的人。如果您使用 Xamarin Forms 并在单独的解决方案中引用类库项目,请注意,如果您遇到与上述类似的错误反射或错误,则问题的原因可能是 MonoAndroid 9 和 NetCore 2.1 之间的不兼容。在我的情况下,解决此问题的方法是对 DB 任务使用单独的解决方案 NetCore 2.1 版本,并在同一个 XF 解决方案中添加同一个类库项目,然后将其转换为针对同一个 NetStandard 框架,因为这就是 Xamarin Forms 的目的目标。

【讨论】:

    【解决方案2】:

    试试这样:

    namespace Custom.Netcore.Models
    {
        [Serializable()]
        [JsonProperty("Model")]
        public class Model
        {
            [JsonProperty("id")]
            public int Id { get; set; }
            [JsonProperty("description")]
            public string Description { get; set; }
            [JsonProperty("Type")]
            public string Type { get; set; }
        }
    }
    

    编辑:

    或尝试使用:

    JsonConvert.DeserializeXmlNode<>
    JsonConvert.DeserializeXNode<>
    

    安装于:

    JsonConvert.DeserializeObject<>
    

    【讨论】:

    • [JsonProperty("name")] 在 DB/API 中没有为我改变任何东西然后尝试使用 xmlnode/xnode 进行反序列化,但仍然遇到相同的错误
    • 首先尝试将 JSON 解析为对象,然后尝试从对象解析为 XML。什么时候可以工作尝试优化。在我看来,你的错误来自于试图解析错误的格式。
    • 如果格式错误,在运行 UWP 而不仅仅是 Android/iOS 时它是否也会失败?在 Android/iOS 上,我仍然可以使用 JsonConvert.DeserializeObject&lt;ObservableCollection&lt;object&gt;&gt;(data); 或更适合迭代以填充集合的方法,在 Android/iOS 模拟器上使用 &lt;Dictionary&lt;string, string&gt;&gt; 并遍历它以填充集合。我的帖子中的“API 数据”示例看起来有问题吗?
    猜你喜欢
    • 2012-09-18
    • 1970-01-01
    • 2012-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多