Question

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
Was it helpful?

Solution 2

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

OTHER TIPS

(this is just a guess and is more fitting for a comment but it's pretty long)

It's possible that the .NET runtime is disposing of the ReplyObject COM object when the BFRWebServiceconnector class goes out of scope, maybe because it is a property of the class and not created within the method?

Try creating the ReplyObject within GetFromBFR instead of making it a property of the class. That also might prevent weird errors from multithreaded access if the COM object is called from different threads.

Also if there's a particular line in the VB program that is throwing the error (after you call GetFromBFR), you could see if the variable is Nothing within VB to try and narrow down the problem.

Like I said, just a guess. Feel free to refute it. :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top