我已更新到最新版本的Xamarin Studio,并且我使用与Visual Studio共享的类不再在两个平台之间工作。我遇到了一些涉及XML序列化的编译/运行时错误。我有一个库,其中包含在Xamarin工作室中编译的以下类:
[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 = neutral,PublicKeyToken = 7cec85d7bea7798e'”<的引用/ p>
当然,我实际上有一个System.Xml的引用。事实上,如果我从Xamarin复制该类并将其粘贴到Visual Studio端的项目中,该类工作正常。根据我如何构建事物,这个错误有一些变化,但这个似乎是根本原因。
任何人都知道为什么这个库不再跨平台工作?在最新版本的Xamarin中,IXmlSerializable发生了什么变化?
答案 0 :(得分:1)
如果你想在Visual Studio中的Xamarin.iOS和你的项目之间共享程序集,你必须确保它们构建在相同的核心库之上(mscorlib,...)
我猜您的Xamarin.iOS项目是基于2.0.5.0
个人资料,而您的其他项目是4.0.0.0
该主题也在forum
上讨论答案 1 :(得分:1)
当然,我实际上有一个对System.Xml的引用。
我遇到了一个类似的问题,我错误地认为有一个using System.Xml
语句没有错误(足够)是一个包含所需类型的引用...特别是因为我没有编译时错误。
显然,即使它允许using System.Xml
(打包在默认的System.Xml库中),它也不包含所需的System.Xml.Serialization.IXmlSerializable
初始System
引用:
所以解决方案是明确添加对Framework
程序集的引用; System.Xml
答案 2 :(得分: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
答案 3 :(得分: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:&gt;“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:&gt; 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。
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\MonoAndroid\v1.0\
再次仅使用此方法作为最后的手段!