Исключение 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
2 ответа
Мне очень стыдно, что причина была очень очень простой... Вместо того, чтобы следовать:
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
...
(это всего лишь предположение и более подходящее для комментария, но оно довольно длинное)
Возможно, что среда выполнения.NET избавляется от ReplyObject
COM-объект, когда BFRWebServiceconnector
класс выходит из области видимости, может быть потому, что он является свойством класса и не создан внутри метода?
Попробуйте создать ReplyObject
в GetFromBFR
вместо того, чтобы сделать его свойством класса. Это также может предотвратить странные ошибки от многопоточного доступа, если COM-объект вызывается из разных потоков.
Кроме того, если в программе VB есть определенная строка, которая выдает ошибку (после вызова GetFromBFR
), вы можете увидеть, если переменная Nothing
в VB, чтобы попытаться сузить проблему.
Как я уже сказал, просто предположение. Не стесняйтесь опровергать это.:)