Iain Fraser
Iain Fraser

Reputation: 6728

NullReferenceException on XML Deserialization in dynamically loaded assembly

I'm writing a plugin for a CMS that loads plugin assemblies dynamically using Assembly.load.

Note: For reasons that are irrelevant to go into, the frontend loads the assembly statically, whilst the admin environment loads it dynamically.

My plugin has its own xml configuration file that loads the first time the plugin class is used. The config file is deserialized into an object object using XmlSerializer.

This deserialization works fine when I load the assembly statically through the frontend, however when the admin tries to load it dynamically I get a NullReferenceException from the reader.

I have tried pre-generating the serialization assembly using Sgen and adding it to the "Bin" directory of the admin environment, but this seems to have no effect.

Stack trace:

[NullReferenceException: Object reference not set to an instance of an object.]
   Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderAccessibilityConfig..cctor() +1156

[TypeInitializationException: The type initializer for 'Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderAccessibilityConfig' threw an exception.]
   Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderAccessibilityConfig..ctor() +0
   Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializerContract.get_Reader() +44
   System.Xml.Serialization.TempAssembly.InvokeReader(XmlMapping mapping, XmlReader xmlReader, XmlDeserializationEvents events, String encodingStyle) +69
   System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) +101

[InvalidOperationException: There is an error in XML document (0, 0).]
   System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) +613
   System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader) +30
   CoA.WebUI.Controls.AccessibilityObjects.AccessibilityConfigBase`1.Deserialize(String xml) +196
   CoA.WebUI.Controls.AccessibilityObjects.AccessibilityConfigBase`1.LoadFromFile(String fileName) +256
   CoA.WebUI.Controls.Accessibility.Configure(Boolean isAdmin) +725
   CoA.WebUI.Controls.Accessibility.GetProperties() +118
   CMS.Admin.WebUI.CustomControlCreator.GetCustomControlProperties() +194
   CMS.Admin.WebUI.CustomControlCreator.BindPropertyControls() +146
   CMS.Admin.WebUI.CustomControlCreator.PageLoad() +164
   CMS.Admin.WebUI.CustomControlCreator.Page_Load(Object sender, EventArgs e) +47
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
   System.Web.UI.Control.OnLoad(EventArgs e) +99
   System.Web.UI.Control.LoadRecursive() +50
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627

Oddly, the stack trace seems to indicate that the XML document is empty, but I'm passing in a StringReader which I have debugged and confirmed is populated with the correct document - it isn't empty.

Upvotes: 2

Views: 1679

Answers (1)

Iain Fraser
Iain Fraser

Reputation: 6728

I figured it out!!!

If anyone else comes across this problem, here is a way of solving it.

Take your serializable object and put it in its own assembly (i.e. its own project in VS). Now you have two dlls. One with your assembly to be dynamically loaded and the other containing your serializable object.

Take the one with your serializeable object and put it in the bin directory of any application that dynamically loads your plugin assembly.

Now when your dynamically loaded assembly tries to create an object, the assembly for creating that object is already available in memory - having been loaded statically.

I don't know why XmlSerializer doesn't like to work when working with a dynamically loaded assembly, but this workaround seems to work well.

Hope this helps someone some day.

Upvotes: 5

Related Questions