I am developing a ComVisible library in .NET which is then called in an old VB6 class. What I basically do in the class is calling a web service, parsing the response and returning an object with necessary data. The web service is designed so that it returns a SoapException
if called with wrong parameter(s). Here is a part of my code:
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;
}
Once I try to call this method from my VB6 code with correct parameters, I get a proper reply. But if I call it with a wrong parameter, I get a -245757
(Object reference was not set to an instance of an object
) runtime error in my VB6 program and it seems that it's not caught by the catch
clause in my C# code (while I would expect an empty ReplyObject
with filled Error
field returned by the method).
I have created a test C# project and copied the same method (i.e. I call the same web service from within the .NET platform) and I can confirm that in this case the SoapException
is being properly caught.
Is this behavior intentional? Is there a way to catch the SoapException
within a ComVisible class (since I really would like to include the error message into my reply object)?
UPD: My VB6 code is following:
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
I'm very ashamed that the reason was very very simple... Instead of following:
catch (Exception ex)
{
_reply.Error = "Error: " + ex.Message;
if (_client.InnerChannel.State == CommunicationState.Faulted) _client = new WCFPersonClient("WSHttpBinding_IWCFPerson"); //recreate the failed channel
}
I had actually following code:
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
}
and it turns out that ex.InnerException
was null
which caused the NullPointerException
...