动态加载的程序集中 XML 反序列化时出现 NullReferenceException

发布于 2025-01-04 09:10:24 字数 2608 浏览 2 评论 0原文

我正在为 CMS 编写一个插件,该插件使用 Assembly.load 动态加载插件程序集。

注意:由于与进入无关的原因,前端静态加载程序集,而管理环境动态加载它。

我的插件有自己的 xml 配置文件,该文件在插件类第一次加载时加载用过的。使用 XmlSerializer 将配置文件反序列化为对象对象。

当我通过前端静态加载程序集时,这种反序列化工作正常,但是当管理员尝试动态加载它时,我会从阅读器处收到 NullReferenceException

我尝试使用 Sgen 预生成序列化程序集并将其添加到管理环境的“Bin”目录中,但这似乎没有效果。

堆栈跟踪:

[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

奇怪的是,堆栈跟踪似乎表明 XML 文档是空的,但我传入了一个 StringReader,我已经调试并确认它填充了正确的文档 - 它不是空的。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

背叛残局 2025-01-11 09:10:24

我想通了!!!

如果其他人遇到这个问题,这里有一个解决方法。

将您的可序列化对象放入其自己的程序集中(即 VS 中其自己的项目)。现在你有两个 dll。一个包含要动态加载的程序集,另一个包含可序列化对象。

将带有可序列化对象的文件放入动态加载插件程序集的任何应用程序的 bin 目录中。

现在,当动态加载的程序集尝试创建对象时,用于创建该对象的程序集已在内存中可用 - 已被静态加载。

我不知道为什么 XmlSerializer 不喜欢在使用动态加载的程序集时工作,但此解决方法似乎效果很好。

希望有一天这会对某人有所帮助。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文