Открытый элемент 'elements' типа 'DBNull' не найден - PullRequest
1 голос
/ 22 февраля 2012

У нас есть компонент ActiveX, который отображает веб-страницу в окне Internet Explorer через SHDocVw. В обработчике события DocumentComplete мы пытаемся извлечь значение из одного из элементов управления на странице. Мы знаем , что элемент управления находится на странице (он виден через Fiddler trace).

Именно в этот момент все становится шатким. Мы получаем следующее сообщение об ошибке во время выполнения:

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().

Ответы [ 3 ]

5 голосов
/ 04 апреля 2012

Вы боретесь с ошибкой в ​​DLR, динамической среде исполнения языка, которая была добавлена ​​в .NET 4. Код в трассировке стека связан с привязкой VB.NET к DLR. Эта ошибка почти наверняка не вызвана кодом, который вы разместили, скорее всего, это будет какой-то другой код в вашем проекте, который делает что-то с запросом dbase. Учитывая наличие DBNull в сообщении об исключении.

Вам понадобится поддержка от Microsoft, чтобы разобраться в этом. Им понадобится ваш проект, чтобы дать им репродукцию для работы, учитывая, что сам фрагмент кода не поможет им его найти. Вы можете связаться со службой поддержки Microsoft, чтобы начать это. Они заберут кусок вашей кредитной карты, но вы почти наверняка получите его обратно, учитывая, что это может быть ошибкой в ​​их коде, а не в вашем.

Существует возможный обходной путь для этой конкретной ошибки, хотя точно не гарантируется, что повреждение DLR не вызовет каких-либо проблем в дальнейшем. Вы можете написать точно такой же код без использования DLR, написав код с ранней привязкой. Начните с Project + Add Reference, перейдите на вкладку Browse и выберите c: \ windows \ system32 \ mshtml.tlb

Затем перепишите свой фрагмент, чтобы он выглядел так:

    Dim doc = DirectCast(Me.IEInstance.ActiveXInstance, mshtml.IHTMLDocument2)
    Dim form = DirectCast(doc.forms("frmRedirect"), mshtml.IHTMLFormElement)
    If form IsNot Nothing Then
        Dim elem = DirectCast(form.elements("redirectData"), mshtml.IHTMLInputElement)
        If elem IsNot Nothing Then
            elem.value = outlookXML.OuterXml
        End If
    End If
0 голосов
/ 07 августа 2012

Чтобы попытаться помочь другим людям, которые смотрят на эту же проблему ... Я проверял данные склада в течение многих лет. Мне нравится видеть веб-страницу, которая очищается, так как она значительно облегчает отладку.
Я использую 64-битную Windows 7, Visual Studio 2010. Когда мой компьютер автоматически переключился на IE9 - у меня начались большие проблемы с кодом, который работал много лет. Код в VB.NET выглядит так:

Public WithEvents MyExplorer As SHDocVw.InternetExplorer
MyExplorer.Navigate("SomeURL")
While (MyExplorer.ReadyState <> SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE)
    Application.DoEvents()
    Thread.Sleep(500)
End While
Dim strHtml As String
strHtml = MyExplorer.Document.DocumentElement.innerHTML.Replace("&amp;", "&").replace("&nbsp;", " ")

Мне пришлось сделать два значительных изменения после выхода IE9: 1. MyExplorer.ReadyState <> SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE 2. MyExplorer.Document.DocumentElement.innerHTML

В первом случае я делал что-то вроде Пока (MyExplorer.Document.readyState <> "complete") это больше не кажется надежным. Я изменился на: Хотя (MyExplorer.ReadyState <> SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE) который кажется более надежным

Во втором случае я получал HTML-код веб-страницы, используя: MyExplorer.Document.documentElement.innerhtml Я продолжал получать исключения, что хотя MyExplorer.ReadyState было завершено - documentElement был нулевым (или DBNull). Интересно было то, что в Intellisense и «Локальных переменных» Visual Studio - я мог видеть documentElement и innerhtml.
Исходя из того, что я видел в одном ответе выше, я просто изменил заглавные буквы DocumentElement, и теперь он, похоже, работает надежно.
Огромным преимуществом VB.NET является то, что он должен быть нечувствительным к регистру ...

0 голосов
/ 28 марта 2012

Что оценивают следующие выражения?

Me.IEInstance.Document.forms
Me.IEInstance.Document.forms("frmRedirect")
Me.IEInstance.Document.forms(0)

Я не знаю, что коллекцию форм можно проиндексировать по имени, но, возможно, я ошибаюсь в этом.Пожалуйста, проверьте все выражения.

Какое отношение имеет элемент ActiveX к вашему вопросу?Похоже, ваш вопрос касается только этой строки кода.Я здесь ошибаюсь?

Редактировать: вот обходной путь: назначьте идентификатор для скрытого ввода и получите элемент ввода по идентификатору.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...