SoapException не перехватывается в классе ComVisible

Я разрабатываю библиотеку ComVisible в .NET, которая затем вызывается в старом классе VB6. Что я в основном делаю в классе, так это вызываю веб-службу, анализирую ответ и возвращаю объект с необходимыми данными. Веб-служба разработана таким образом, что она возвращает SoapException при вызове с неправильным параметром (параметрами). Вот часть моего кода:

    private static WCFPersonClient _client;
    private static ReplyObject _reply;

    public BFRWebServiceconnector()
    {
        _client = new WCFPersonClient("WSHttpBinding_IWCFPerson");
        _reply = new ReplyObject ();            
    }

    [ComVisible(true)]
    public ReplyObject GetFromBFR(string bestallningsID, string personnr, bool reservNummer = false)
    {
        try
        {
            var response = new XmlDocument();

            //the service operation returns XML but the method in the generated service reference returns a string for some reason               
            var responseStr = _client.GetUserData(orderID, personnr, 3); reason.

            response.LoadXml(responseStr);
            //parse the response and fill the reply object
            .......
        }
        catch (Exception ex)
        {
            _reply.Error = "Error: " + ex.Message;
            if (_client.InnerChannel.State == CommunicationState.Faulted) _client = new WCFPersonClient("WSHttpBinding_IWCFPerson"); //recreate the failed channel
        }
        return _reply;
    }

Как только я пытаюсь вызвать этот метод из своего кода VB6 с правильными параметрами, я получаю правильный ответ. Но если я вызываю его с неправильным параметром, я получаю ошибку времени выполнения -245757 (Object reference was not set to an instance of an object) в моей программе VB6, и кажется, что она не улавливается предложением catch в моем коде C# (в то время как я ожидал бы пустой ReplyObject с заполненным полем Error возвращается методом).

Я создал тестовый проект C# и скопировал тот же метод (т.е. я вызываю ту же веб-службу из платформы .NET), и я могу подтвердить, что в этом случае SoapException правильно перехватывается.

Является ли это поведение преднамеренным? Есть ли способ поймать SoapException в классе ComVisible (поскольку я действительно хотел бы включить сообщение об ошибке в свой объект ответа)?

UPD: Мой код VB6 следующий:

Set BFRWSCReply = New ReplyObject
Set BFRWSC = New BFRWebbServiceconnector
Set BFRWSCReply = BFRWSC.GetFromBFR(m_BeställningsID, personnr)

If Not IsNull(BFRWSCReply) Then
    If BFRWSCReply.Error= "" Then
       m_sEfternamn = BFRWSCReply.Efternamn
       //etc i.e. copy fields from the ReplyObject
    Else
       MsgBox BFRWSCReply.Error, vbExclamation
    End If
End If

person Azimuth    schedule 04.01.2013    source источник
comment
Возможно, объект _replay не инициализирован, пока в предложении catch установлена ​​ошибка: _reply.Error = "Error: " + ex.Message;   -  person Algirdas    schedule 04.01.2013
comment
@algirdas, нет, он инициализируется в конструкторе.   -  person Azimuth    schedule 04.01.2013
comment
Что такое ошибка времени выполнения от VB?   -  person D Stanley    schedule 04.01.2013
comment
@DStanley это -245757 Error 1 - Application-defined or object-defined error : Object reference not set to an instance of an object.   -  person Azimuth    schedule 04.01.2013
comment
ReplyObject тоже помечен как ComVisible?   -  person D Stanley    schedule 04.01.2013
comment
@DStanley да, это тоже ComVisible.   -  person Azimuth    schedule 04.01.2013
comment
Возврат глобальных переменных напрашивается на неприятности. Обязательно используйте отладчик, его настройка для отладки кода VB6 и C# описана в этом ответе: stackoverflow.com/a/ 11975581/17034   -  person Hans Passant    schedule 04.01.2013
comment
@HansPassant, к сожалению, я не могу отлаживать программу, так как веб-сервис доступен только с тестовой машины через VPN, где у меня нет VisualStudio...   -  person Azimuth    schedule 04.01.2013
comment
@Azimuth, тогда мое предположение о области действия, вероятно, неверно, поскольку данные для класса маршалируются, служба может делать с объектами все, что захочет. Вы пытаетесь получить доступ к определенному свойству ReplyObject при возникновении исключения?   -  person D Stanley    schedule 04.01.2013
comment
@DStanley, вы имеете в виду код VB6? Если это так, то да, я проверяю, пусто ли поле Error, и если нет, я пытаюсь прочитать другие поля объекта. Я обновил вопрос своим кодом VB6.   -  person Azimuth    schedule 04.01.2013


Ответы (2)


(это всего лишь предположение и больше подходит для комментария, но оно довольно длинное)

Возможно, что среда выполнения .NET избавляется от COM-объекта ReplyObject, когда класс BFRWebServiceconnector выходит за рамки, возможно, потому, что он является свойством класса, а не создается внутри метода?

Попробуйте создать ReplyObject внутри GetFromBFR вместо того, чтобы сделать его свойством класса. Это также может предотвратить странные ошибки многопоточного доступа, если COM-объект вызывается из разных потоков.

Кроме того, если в программе VB есть определенная строка, которая выдает ошибку (после вызова GetFromBFR), вы можете посмотреть, является ли переменная Nothing в VB, чтобы попытаться сузить проблему.

Как я уже сказал, просто предположение. Смело опровергайте это. :)

person D Stanley    schedule 04.01.2013
comment
Я попытаюсь создать ReplyObject в методе. Как-то я сам пропустил этот момент... - person Azimuth; 04.01.2013

Мне очень стыдно, что причина была очень-очень проста... Вместо следующего:

catch (Exception ex)
    {
        _reply.Error = "Error: " + ex.Message;
        if (_client.InnerChannel.State == CommunicationState.Faulted) _client = new WCFPersonClient("WSHttpBinding_IWCFPerson"); //recreate the failed channel
    }

На самом деле у меня был следующий код:

catch (Exception ex)
    {
        _reply.Error = "Error: " + ex.Message + "; " + ex.InnerException.Message;
        if (_client.InnerChannel.State == CommunicationState.Faulted) _client = new WCFPersonClient("WSHttpBinding_IWCFPerson"); //recreate the failed channel
    }

и оказывается, что ex.InnerException было null, что вызвало NullPointerException...

person Azimuth    schedule 07.01.2013