公共成员“元素”;在类型“DBNull”上未找到
我们有一个 ActiveX 组件,它通过 SHDocVw 在 Internet Explorer 窗口中显示网页。在 DocumentComplete 事件处理程序中,我们尝试从页面上的控件之一检索值。我们知道该控件位于页面上(通过 Fiddler 跟踪可见)。
正是在这一点上,事情变得不稳定。我们在运行时收到以下错误消息:
Error Message:
Public member 'elements' on type 'DBNull' not found.
Error Routine Location:
at Microsoft.VisualBasic.CompilerServices.Symbols.Container.GetMembers(String& MemberName, Boolean ReportErrors)
at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)
at Foo.AddinModule.m_internetExplorer_DownloadComplete(Object pDisp, Object& url)
Error Source:
Microsoft.VisualBasic
Error Site Location:
System.Reflection.MemberInfo[] GetMembers(System.String ByRef, Boolean)
有问题的代码行是这样的:
Me.IEInstance.Document.forms("frmRedirect").elements("redirectData").Value = outlookXML.OuterXml
因此,本质上,Me.IEInstance.Document.forms("frmRedirect")
正在评估 DBNull
代码>.
我们已经消除了区分大小写的问题。尝试在页面内移动控件,并验证 HTML 格式是否正确。我不知道为什么会发生这种情况。下面是生成的 HTML 示例。
谁能提出这个问题的原因和可能的解决方案?目前我正在考虑所有建议。
HTML 示例
<form id='frmRedirect' name='frmRedirect' action='pw_outlook/choosecontacts.aspx' method='POST'>
<input type='hidden' name='redirectData'>
</form>
更新 3/28/2012
我们已确定代码在某些配置下可以正常工作。然后,神秘的是,如果您按如下方式更改代码,对于某些用户将会成功:
Me.IEInstance.Document.forms("frmRedirect").Elements("redirectData").Value = outlookXML.OuterXml
^
^
也就是说,如果您只是更改 Elements
的大小写。对我来说,这有点像 COM vtable 查找过程中的区分大小写问题,但神秘的是并不是每个人都会发生这种情况。只是一些用户。
另外,请注意 .forms("frmRedirect")
返回的表单是一个有效的对象;但是,它似乎没有 elements()
方法。
We have an ActiveX component that displays a Web page in an Internet Explorer window via SHDocVw. In the DocumentComplete event handler, we attempt to retrieve the value from one of the controls on the page. We know the control is on the page (it's visible via a Fiddler trace).
It's at this point that things get wonky. We receive the following error message at runtime:
Error Message:
Public member 'elements' on type 'DBNull' not found.
Error Routine Location:
at Microsoft.VisualBasic.CompilerServices.Symbols.Container.GetMembers(String& MemberName, Boolean ReportErrors)
at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)
at Foo.AddinModule.m_internetExplorer_DownloadComplete(Object pDisp, Object& url)
Error Source:
Microsoft.VisualBasic
Error Site Location:
System.Reflection.MemberInfo[] GetMembers(System.String ByRef, Boolean)
The offending line of code is this one:
Me.IEInstance.Document.forms("frmRedirect").elements("redirectData").Value = outlookXML.OuterXml
So, essentially, Me.IEInstance.Document.forms("frmRedirect")
is evaluating to DBNull
.
We've eliminated case sensitivity issues. Tried moving the control around within the page, and verified that the HTML is well-formed. I have no idea why this is occurring. A sample of the generated HTML is below.
Can anyone suggest a cause and a possible resolution for this issue? I'm entertaining any and all suggestions at this point.
HTML Sample
<form id='frmRedirect' name='frmRedirect' action='pw_outlook/choosecontacts.aspx' method='POST'>
<input type='hidden' name='redirectData'>
</form>
UPDATE 3/28/2012
We have determined that the code works fine under certain configurations. Then, mysteriously, it will succeed for some users if you change the code as follows:
Me.IEInstance.Document.forms("frmRedirect").Elements("redirectData").Value = outlookXML.OuterXml
^
^
That is, if you simply change the case of Elements
. This, to me, smacks of a case sensitivity issue during a COM vtable lookup, but the mystery is that it doesn't occur for everyone. Just some users.
Also, please note that the form that is returned by .forms("frmRedirect")
is a valid object; however, it doesn't appear to have an elements()
method.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您正在与 DLR(.NET 4 中添加的动态语言运行时)中的错误作斗争。堆栈跟踪上的代码与 DLR 的 VB.NET 绑定器相关。这个错误几乎肯定不是由您发布的代码触发的,它可能是您项目中的其他代码使用数据库查询执行某些操作。鉴于异常消息中存在 DBNull。
您需要 Microsoft 的支持才能查明真相。鉴于代码片段本身无法帮助他们找到它,他们需要您的项目为他们提供重现。您可以联系 Microsoft 支持来开始使用。他们会从你的信用卡中扣除一大笔钱,但你几乎肯定会拿回来,因为这很可能是他们代码中的错误,而不是你的代码中的错误。
对于此特定故障,有一个可能的解决方法,但不能完全保证 DLR 损坏不会在以后引起某种问题。您可以通过编写早期绑定代码来编写完全相同的代码,而无需使用 DLR。从“项目 + 添加引用”、“浏览”选项卡开始,选择 c:\windows\system32\mshtml.tlb
然后重写代码片段,如下所示:
You are battling a bug in the DLR, the dynamic language runtime that was added in .NET 4. The code on the stack trace is related to the VB.NET binder to the DLR. This bug is almost certainly not triggered by the code you posted, it is likely to be some other code in your project that does something with a dbase query. Given the presence of DBNull in the exception message.
You'll need support from Microsoft to get to the bottom of this. They'll need your project to give them a repro to work on, given that the code snippet itself won't help them find it. You can contact Microsoft Support to get that started. They'll take a chunk out of your credit card but you'll almost certainly get it back, given that it is likely to be a bug in their code and not yours.
There is a possible workaround for this particular failure, although it isn't exactly guaranteed that the DLR corruption isn't going to cause some kind of problem later. You can write the exact same code without using the DLR by writing early bound code. Start that with Project + Add Reference, Browse tab, select c:\windows\system32\mshtml.tlb
Then rewrite your snippet to look like this:
以下表达式的计算结果是什么?
我不知道表单集合可以按名称索引,但也许我错了。请验证所有表达式。
ActiveX 控件与您的问题有什么关系?看来你的问题只是关于那一行有问题的代码。我这里是不是搞错了?
编辑:这里有一个解决方法:为隐藏输入分配一个 ID,并通过 id 获取输入元素。
What do the following expressions evaluate to?
I don't know that the forms collection can be indexed by name, but maybe I am wrong on this. Please verify all the expressions.
What does the ActiveX-control have to do with your question? It seems that your question is only about that offending line of code. Am I mistaken here?
Edit: Here is a workaround: assign an ID to the hidden input and get the input element by id.
试图帮助其他正在考虑同样问题的人......
多年来我一直在屏幕上抓取股票数据。我喜欢看到正在抓取的网页,因为它使调试变得更加容易。
我运行 Windows 7 64 位、Visual Studio 2010。当我的计算机自动更改为 IE9 时,我开始在运行多年的代码中遇到很多问题。 VB.NET 中的代码如下:
自从 IE9 出现以来,我不得不做出两个重大更改:
1. MyExplorer.ReadyState>> SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE
2. MyExplorer.Document.DocumentElement.innerHTML
在第一种情况下,我正在做类似的事情
While (MyExplorer.Document.readyState<>“完成”)
这似乎不再可靠。我改为:
while (MyExplorer.ReadyState <> SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE)
这似乎更可靠
在第二种情况下,我通过使用以下方式获取网页的 HTML:
MyExplorer.Document.documentElement.innerhtml
我不断收到异常,尽管 MyExplorer.ReadyState 已完成 - documentElement 为 null(或 DBNull)。有趣的部分是,在 Visual Studio 的 Intellisense 和“局部变量”中 - 我可以看到 documentElement 和 insidehtml。
根据我在上面的一个答案中看到的内容 - 我只是更改了 DocumentElement 的大小写,现在它似乎可以可靠地工作。
VB.NET 的巨大优势是它不区分大小写......
To try to help out other people that looking at this same issue ...
I have been screen scraping stock data for many years. I like to see the web page that is being scraped since it makes it much easier to debug.
I run Windows 7 64 bit, Visual Studio 2010. When my computer automatically changed to IE9 - I started having a lot of problems with code that had been running for many years. The code in VB.NET is like:
I have had to make two significant changes since IE9 came out:
1. MyExplorer.ReadyState <> SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE
2. MyExplorer.Document.DocumentElement.innerHTML
In the first case I was doing something like
While (MyExplorer.Document.readyState <> "complete")
that no longer seems to work reliably. I changed to:
While (MyExplorer.ReadyState <> SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE)
which seems more reliable
In the second case I was getting the HTML of the web page by using:
MyExplorer.Document.documentElement.innerhtml
I kept getting exceptions that although MyExplorer.ReadyState was complete - documentElement was null (or DBNull). The interesting part was that in Intellisense and "Local Variables" of Visual Studio - I could see documentElement and innerhtml.
Based on what I saw in one answer above - I simply changed the capitalization of DocumentElement and it now seems to work reliably.
The huge advantage of VB.NET is that it is suppose to be case insensitive ...