我在我的類中使用不同於使用默認序列化程序生成的XML結構進行序列化/反序列化的方法。這些方法爲我的類型創建了一個XmlSerializer,但有一大堆覆蓋。當這些方法被調用時,我猜內部.NET仍然會生成一個序列化程序集,但是我想在編譯後生成這個程序集,所以它不會在運行時生成。我如何生成這個自定義序列化的序列化程序集?如果我爲該類型使用sgen.exe,它似乎只會生成默認的序列化程序。爲自定義XmlSerializer生成一個Xml序列化程序集
特別是我需要生成序列化程序集的原因是我的代碼是從Internet Explorer進程中調用的,該程序在保護模式下運行。如果.net運行時嘗試生成序列化程序集,它會調用csc.exe,並提示用戶詢問是否允許運行此進程。我不希望用戶被提示!所以需要在沒有csc.exe的情況下完成所有序列化/反序列化。
我能想到的一個選擇是捕獲在運行時生成的.cs文件,並將其放入單獨的程序集中,然後將其包含在我的產品中。除了有點噁心,這引發瞭如何自動生成.cs作爲我的構建過程的一部分...
也許還值得一提:我的自定義XML序列化也序列化嵌套類,所以也許那裏也會自動生成序列化程序。我的自定義序列化大部分都是按照以下幾行完成的 - 它將XmlIgnore添加到某些屬性並從其他位置移除XmlIgnore。許多這些屬性返回需要序列化的對象,其中一些實現IXmlSerializable,一些使用默認序列化。
public void SerializeToCustomXml1(XmlWriter writer)
{
try
{
CustomXmlSerializer1.Serialize(writer, this);
}
catch (Exception)
{
}
}
/// <summary>
/// Static serializer so it's created just once. There's another one like this CustomXmlSerializer2 with a slightly different format again.
/// </summary>
private static XmlSerializer CustomXmlSerializer1
{
get
{
if (_customXmlSerializer == null)
{
XmlAttributes dontIgnore = new XmlAttributes();
dontIgnore.XmlIgnore = false;
XmlAttributes attributes;
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
// Include some fields in the XML that wouldn't be there otherwise.
overrides.Add(typeof (WebResource), "ID", dontIgnore);
overrides.Add(typeof (WebResource), "HasDestinationURLs", dontIgnore);
overrides.Add(typeof (Resource), "AccessDefindBy", dontIgnore);
attributes = new XmlAttributes();
attributes.XmlIgnore = false;
attributes.XmlElements.Add(new XmlElementAttribute("ActionID"));
overrides.Add(typeof(Action), "ID", attributes);
// Instead of serializing the Actions field we serialize CustomActionsXmlSerializer,
// which outputs different content in the XML
overrides.Add(typeof (WebResource), "Actions", ignore);
attributes = new XmlAttributes();
attributes.XmlIgnore = false;
attributes.XmlElements.Add(new XmlElementAttribute("Actions"));
overrides.Add(typeof (WebResource), "CustomActionsXmlSerializer", attributes);
// ... more of these overrides here ...
_customXmlSerializer1 = new XmlSerializer(typeof(WebResource), overrides);
}
return _customXmlSerializer1;
}
UPDATE: 哦,this answer表明,它只是不可能的,因爲XmlSerializer的甚至不找一個預編譯的組件,如果你正在使用XmlOverrides。該死。然後我猜我最好的選擇是生成序列化代碼並將其包含在我的項目中,並直接調用它而不是調用XmlSerializer。任何想法如何做到這一點整齊?
啊,直到現在我還沒有看到你在使用XmlOverrides。你真的需要這樣做嗎?或者你可以通過實現'IXmlSerializable'來實現嗎?從你的代碼中,我會說通過使用靜態的'[XmlAttribute]'和'IXmlSerializable',你所做的大部分事情都可以通過覆蓋來實現。 –
我使用XmlOverrides,因爲我有三種不同的XML格式,我正在序列化到。一個使用默認的序列化,另外兩個使用XmlSerializer對象和一大堆覆蓋。我認爲IXmlSerializable只會讓我選擇輸出到一種格式。 – Rory
使用'IXmlSerializable',您可以從'XmlReader'或'XmlWriter'手動讀寫元素和屬性,這樣您就可以完全掌控您想要如何讀寫數據。假設你正在序列化或反序列化的上下文,你可以做許多'if's並且有你想要的許多代碼路徑。 –