1

我已更新到最新版本的 Xamarin Studio,并且我使用的与 Visual Studio 共享的类不再在这两个平台之间工作。我遇到了一些涉及 XML 序列化的编译/运行时错误。我有一个在 Xamarin Studio 中编译的包含以下类的库:

[XmlRoot("dictionary")]
[Serializable]
public class SerializableDictionary<TKey, TValue>
    : Dictionary<TKey, TValue>, IXmlSerializable
{
    #region IXmlSerializable Members

    public SerializableDictionary()
    {

    }

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(System.Xml.XmlReader reader)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

        bool wasEmpty = reader.IsEmptyElement;
        reader.Read();

        if (wasEmpty)
            return;

        while (reader.NodeType != System.Xml.XmlNodeType.EndElement)
        {
            reader.ReadStartElement("item");

            reader.ReadStartElement("key");
            TKey key = (TKey)keySerializer.Deserialize(reader);
            reader.ReadEndElement();

            reader.ReadStartElement("value");
            TValue value = (TValue)valueSerializer.Deserialize(reader);
            reader.ReadEndElement();

            this.Add(key, value);

            reader.ReadEndElement();
            reader.MoveToContent();
        }
        reader.ReadEndElement();
    }

    public void WriteXml(System.Xml.XmlWriter writer)
    {
        XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

        foreach (TKey key in this.Keys)
        {
            writer.WriteStartElement("item");

            writer.WriteStartElement("key");
            keySerializer.Serialize(writer, key);
            writer.WriteEndElement();

            writer.WriteStartElement("value");
            TValue value = this[key];
            valueSerializer.Serialize(writer, value);
            writer.WriteEndElement();

            writer.WriteEndElement();
        }
    }
    #endregion
}

我已经编译了这个 DLL 并在 Visual Studio 的 Windows 项目中引用它,如下所示:

SerializableDictionary<string, string> asdf = new SerializableDictionary<string, string>();

这会产生编译错误:“类型'System.Xml.Serialization.IXmlSerializable'在未引用的程序集中定义。您必须添加对程序集'System.Xml,Version = 2.0.5.0,Culture =中性的引用, PublicKeyToken=7cec85d7bea7798e'"

当然,我确实有对 System.Xml 的引用。事实上,如果我从 Xamarin 复制该类并将其粘贴到 Visual Studio 端的项目中,则该类可以正常工作。根据我构建事物的方式,此错误有一些变体,但这似乎是根本原因。

任何人都知道为什么这个库不再跨平台工作?最新版本的 Xamarin 中的 IXmlSerializable 是否发生了一些变化?

4

4 回答 4

1

如果要在 Xamarin.iOS 和 Visual Studio 中的项目之间共享程序集,则必须确保它们构建在相同的核心库(mscorlib,...)之上

我猜你的 Xamarin.iOS 项目是在2.0.5.0配置文件上构建的,而你的其他项目是在4.0.0.0

这个话题也在论坛上讨论

于 2013-11-26T11:10:34.463 回答
1

当然,我确实有对 System.Xml 的引用。

我遇到了一个类似的问题,我错误地认为有一个using System.Xml没有错误的语句是(足够)包含所需类型的引用......特别是因为我没有编译时错误。

使用 System.Xml

显然,即使它允许using System.Xml(打包在默认的 System.Xml 库中),它也没有包含所需的System.Xml.Serialization.IXmlSerializable

初步System参考:

当前系统参考

所以解决方案是明确添加对Framework大会的引用;System.Xml

显式引用 System.Xml 程序集

于 2016-03-07T11:36:34.163 回答
0

System.XML 命名空间既存在于 System.XML 程序集中,也存在于 System.Data 中(这是造成混淆的原因)

Teemu 准确地解释了这一点:https ://bytes.com/topic/asp-net/answers/645579-you-must-add-reference-assembly-system-xml

帖子如下:你好,

使用 System.Xml;

并不意味着您会参考 System.Xml.dll 程序集。这意味着您只是在导入该命名空间,试图缩短键入驻留在 System.Xml 命名空间中的类型的完全限定名称的需要。

命名空间是逻辑概念,它们不一定总是与程序集齐头并进。例如: System.Configuration 命名空间跨越两个程序集:System.dll 和 System.Configuration.dll

因此,请尝试在 VS 中使用添加引用对话框(/右键单击

解决方案资源管理器中的项目)

Teemu Keiski AspInsider,ASP.NET MVP

于 2016-04-27T17:55:21.957 回答
0

从我的角度来看,Stephane Delcroix 正确回答了这个问题,但您可以这样做:

请注意,如果您可以控制外部库,则不应使用此方法。您应该为 Xamarin 目标编译它们或使用 .net 标准库/PCL。

只能将此方法作为最后的手段!

但是,如果您无法控制外部库并且仍需要在 Xamarin 应用程序中使用它们,那么您可以执行以下操作:

请注意,这些说明适用于 Android,但同样的方法可能适用于 iOS。

修改 Xamarin System.Xml.dll 文件,使其具有与所需 System.Xml.dll 相同的版本。

  • 复制C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\MonoAndroid\v1.0\System.Xml到可写位置。(我们称之为E:\

  • 反汇编 System.Xml.dll:

    E:>"c:\Program Files (x86)\Microsoft SDKs\Windows_v7.0A\Bin\ildasm.exe" System.Xml.dll /out=e:/System.Xml.asm"

  • 修改 asm

您可以使用此补丁(作为指南):

--- E:\System.Xml.orig.asm
+++ E:\System.Xml.asm
@@ -127,19 +127,10 @@
   .custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78   // ....T..WrapNonEx
                                                                                                              63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 )       // ceptionThrows.
   .permissionset reqmin
-             = {class 'System.Security.Permissions.SecurityPermissionAttribute, mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e' = {property bool 'SkipVerification' = bool(true)}}
-  .publickey = (00 24 00 00 04 80 00 00 94 00 00 00 06 02 00 00   // .$..............
-                00 24 00 00 52 53 41 31 00 04 00 00 01 00 01 00   // .$..RSA1........
-                8D 56 C7 6F 9E 86 49 38 30 49 F3 83 C4 4B E0 EC   // .V.o..I80I...K..
-                20 41 81 82 2A 6C 31 CF 5E B7 EF 48 69 44 D0 32   //  A..*l1.^..HiD.2
-                18 8E A1 D3 92 07 63 71 2C CB 12 D7 5F B7 7E 98   // ......cq,..._.~.
-                11 14 9E 61 48 E5 D3 2F BA AB 37 61 1C 18 78 DD   // ...aH../..7a..x.
-                C1 9E 20 EF 13 5D 0C B2 CF F2 BF EC 3D 11 58 10   // .. ..]......=.X.
-                C3 D9 06 96 38 FE 4B E2 15 DB F7 95 86 19 20 E5   // ....8.K....... .
-                AB 6F 7D B2 E2 CE EF 13 6A C2 3D 5D D2 BF 03 17   // .o}.....j.=]....
-                00 AE C2 32 F6 C6 B1 C7 85 B4 30 5C 12 3B 37 AB ) // ...2......0\.;7.
+             = {class 'System.Security.Permissions.SecurityPermissionAttribute, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' = {property bool 'SkipVerification' = bool(true)}}
+  .publickey = (00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 ) 
   .hash algorithm 0x00008004
-  .ver 2:0:5:0
+  .ver 4:0:0:0
 }
 .module System.Xml.dll
 // MVID: {4AB28EE6-F5EC-49E1-A1A7-69D0920BF2EC}
@@ -149,7 +140,7 @@
 .stackreserve 0x00100000
 .subsystem 0x0003       // WINDOWS_CUI
 .corflags 0x00000001    //  ILONLY
-// Image base: 0x05580000
+// Image base: 0x05300000


 // =============== CLASS MEMBERS DECLARATION ===================
@@ -201,7 +192,7 @@
   .field public static literal string FxFileVersion = "4.0.50524.0"
   .field public static literal string EnvironmentVersion = "4.0.50524.0"
   .field public static literal string VsFileVersion = "9.0.50727.42"
-  .field private static literal string PublicKeyToken = "7cec85d7bea7798e"
+  .field private static literal string PublicKeyToken = "b77a5c561934e089"
   .field public static literal string AssemblyI18N = "I18N, Version=2.0.5.0, Culture=neutral, PublicKeyT"
   + "oken=0738eb9f132ed756"
   .field public static literal string AssemblyMicrosoft_JScript = "Microsoft.JScript, Version=2.0.5.0, Culture=neutra"
@@ -619213,4 +619204,4 @@
 .data D_00273E18 = bytearray (
                  20 00 09 00 0A 00 0D 00)                         //  .......
 // *********** DISASSEMBLY COMPLETE ***********************
-// WARNING: Created Win32 resource file e:/System.Xml.orig.res+// WARNING: Created Win32 resource file e:/System.Xml.res

这会将 2.0.5.0 版本号更改为 4.0.0.0 并更新公钥令牌。(从 7cec85d7bea7798e 到 b77a5c561934e089)

  • 重新组装

    E:>c:\Windows\Microsoft.NET\Framework\v4.0.30319\ilasm.exe /dll /output=System.Xml.dll System.Xml.asm /Resource=System.Xml.res

首先备份原始 System.Xml.dll。

  • 将“固定” System.Xml 复制回C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\MonoAndroid\v1.0\

再次仅将此方法用作最后的手段!

于 2017-05-09T21:35:47.617 回答