生成XML序列化程序集的自定义的XmlSerializer [英] Generating an Xml Serialization assembly for a custom XmlSerializer

查看:198
本文介绍了生成XML序列化程序集的自定义的XmlSerializer的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的类中的方法进行序列化/使用不同的XML结构比会使用默认的序列化产生反序列化。该方法创建一个XmlSerializer为我喜欢的类型,但有一大堆覆盖的。当调用这些方法我在内部猜.NET将仍然生成一个序列化程序集,但我想编译后生成该组件所以它不是在运行时产生的。我怎样才能生成一个序列化程序为这个自定义序列?如果我使用sgen.exe该类型似乎只生成默认的序列。

I have methods in my class for serializing/deserializing using a different XML structure than what would be produced with the default serializer. The methods create an XmlSerializer for my type but with a whole bunch of overrides. When these methods are called I guess internally .NET still generates a serialization assembly but I would like to generate this assembly after compilation so it's not generated at runtime. How can I generate a serialization assembly for this custom serialization? If I use sgen.exe for that type it appears to only generate the default serializer.

在我特别需要生成序列化程序集的原因是,我的code为从Internet Explorer进程,它运行在保护模式下调用。如果.NET运行时尝试生成序列化程序集调用csc.exe的,并会提示用户,询问是否允许运行此程序。我不希望提示用户!因此需要在不csc.exe的完成所有的序列化/反序列化。

In particular the reason I need to generate the serialization assembly is that my code is called from within Internet Explorer process, which runs in Protected Mode. If the .net runtime tries to generate a serialization assembly it calls csc.exe and the user is prompted, asking whether to allow this process to be run. I don't want users to be prompted! So need all serialization/deserialization to be done without csc.exe.

一个选择,我能想到的是捕捉,这一需要在运行时所产生的.cs,将它放在一个单独的程序,然后包括在我的产品。除了是有点恶心,引发了如何自动生成问题的.cs作为我的构建过程的一部分......

One option I can think of is capturing that .cs that's generated at runtime, putting it in a separate assembly and then including that in my product. Apart from being a bit icky, that raises the problem of how to auto-generate that .cs as part of my build process ...

或许也值得一提:我的自定义XML序列化也连载嵌套类,所以也许会有自动生成的序列化对他们来说。我的自定义序列沿着下面几行主要是做 - 它增加了XmlIgnore某些属性,并删除XmlIgnore他人。其中许多属性的回归将需要被序列化的对象,其中一些实施IXmlSerializable的,一些使用默认的序列化。

Perhaps also worth mentioning: my custom xml serialization also serializes nested classes, so maybe there would be auto-generated serializers for them too. My custom serialization is mostly done along the lines below - it adds XmlIgnore to some properties and removes XmlIgnore from others. Many of these properties return objects that would need to be serialized, some of which implement IXmlSerializable, some use default serialization.

    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;
        }

跨发布<一个href="http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/20f8af01-19c5-4281-9f9a-8e95678cb4fb"相对=nofollow>这里和<一href="http://social.msdn.microsoft.com/Forums/en/asmxandxml/thread/1568a8c4-fa08-4e8b-9c15-903cd66b3a2d"相对=nofollow>这里。

更新: 哦,<一个href="http://stackoverflow.com/questions/678676/$p$pcompile-xmlserializers-with-xmlattributeoverrides/1451168#1451168">this答案表明,它是不可能的因为XmlSerializer的甚至不找一个precompiled组件,如果你使用的是XmlOverrides。织补。那么我想我最好的选择是生成序列化code和包括它在我的项目,并调用调用的XmlSerializer的直接替代。如何做到这一点的任何想法整齐?

UPDATE: Oh, this answer suggests it's just not possible as XmlSerializer doesn't even look for a precompiled assembly if you're using XmlOverrides. Darn. Then I guess my best option is to generate the serialization code and include it in my project and call that directly instead of calling XmlSerializer. Any thoughts on how to do this neatly?

推荐答案

如果您通过自定义XmlSerializer的的意思是,你使用的 System.Xml.XmlSerializer ,提供自定义序列化code(无论是通过的 的IXmlSerializable [的XmlElement] 属性和朋友),就应该寻找 MyAssembly.XmlSerializers.dll 序列化时,称为汇编

If you by "custom XmlSerializer" mean that you use System.Xml.XmlSerializer with custom serialization code (either through IXmlSerializable or [XmlElement] attributes and friends), it should be looking for an assembly called MyAssembly.XmlSerializers.dll when serializing.

该组件的命名是很重要的,如果你不确定是否它正在寻找什么确切的程序集名称正在抬头,你可以附加一个事件处理程序的 AppDomain.CurrentDomain.FirstChanceException ,以火在应用程序域中所有的异常,包括装配装入异常。您还可以挂接到 AppDomain.CurrentDomain .AssemblyLoad < $ C C> AppDomain.CurrentDomain.AssemblyResolve 事件$,这应该解雇每一个组件首次加载到应用程序域的时间。

The naming of the assembly is important, and if you're unsure whether it's being looked for and what exact assembly name is being looked up, you can just attach an event handler to AppDomain.CurrentDomain.FirstChanceException which will fire for all exceptions in the app domain, including assembly loading exceptions. You can also hook into the AppDomain.CurrentDomain.AssemblyLoad and AppDomain.CurrentDomain.AssemblyResolve events, which should fire every time an assembly is first loaded into the app domain.

另一个重要的事情是,版本(也是最重要的,我不知道)的 MyAssembly.dll程序 MyAssembly.XmlSerializers.dll 必须匹配,他们也应该放在彼此旁边。请参见和<一href="http://blogs.msdn.com/b/crm/archive/2009/02/02/boost-performance-with-$p$p-generated-xmlserializers.aspx"相对=nofollow>这个MSDN文章更多信息。

Another important thing is that the version (and perhaps key; I'm not sure) of MyAssembly.dll and MyAssembly.XmlSerializers.dll must match and they should also be placed alongside each other. See this and this MSDN article for more information.

这篇关于生成XML序列化程序集的自定义的XmlSerializer的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆