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.
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.
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 ...
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;
}
Cross-posted here and here.
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?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…