gpt4 book ai didi

c# - 为自定义 XmlSerializer 生成 Xml 序列化程序集

转载 作者:太空宇宙 更新时间:2023-11-03 11:32:29 25 4
gpt4 key购买 nike

我的类中有一些方法可以使用与默认序列化程序生成的不同的 XML 结构进行序列化/反序列化。这些方法为我的类型创建了一个 XmlSerializer,但有一大堆重写。当调用这些方法时,我猜 .NET 内部仍会生成一个序列化程序集,但我想在编译后生成此程序集,因此它不会在运行时生成。如何为此自定义序列化生成序列化程序集?如果我对该类型使用 sgen.exe,它似乎只生成默认的序列化程序。

特别是我需要生成序列化程序集的原因是我的代码是从以保护模式运行的 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;
}

交叉发布 herehere .

更新:哦,this answer建议这是不可能的,因为如果您使用 XmlOverrides,XmlSerializer 甚至不会查找预编译程序集。该死的。那么我想我最好的选择是生成序列化代码并将其包含在我的项目中并直接调用它而不是调用 XmlSerializer。关于如何巧妙地做到这一点有什么想法吗?

最佳答案

如果您使用“自定义 XmlSerializer”意味着您使用 System.Xml.XmlSerializer使用自定义序列化代码(通过 IXmlSerializable[XmlElement] 属性和 friend ),它应该在序列化时寻找名为 MyAssembly.XmlSerializers.dll 的程序集。

程序集的命名很重要,如果您不确定是否正在查找它以及正在查找的确切程序集名称,您可以将事件处理程序附加到 AppDomain.CurrentDomain.FirstChanceException。它将针对应用程序域中的所有异常触发,包括程序集加载异常。您还可以 Hook AppDomain.CurrentDomain.AssemblyLoadAppDomain.CurrentDomain.AssemblyResolve事件,每次程序集首次加载到应用程序域时都应触发。

另一件重要的事情是 MyAssembly.dllMyAssembly.XmlSerializers.dll 的版本(也许是关键;我不确定)必须匹配并且它们应该也并排放置。参见 thisthis MSDN article获取更多信息。

关于c# - 为自定义 XmlSerializer 生成 Xml 序列化程序集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7333689/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com