SoapException未在ComVisible类中捕获

时间:2013-01-04 11:15:15

标签: c# interop comvisible soapexception

我正在.NET中开发一个ComVisible库,然后在旧的VB6类中调用它。我在类中基本上做的是调用Web服务,解析响应并返回包含必要数据的对象。 Web服务的设计使得如果使用错误的参数调用它将返回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代码中使用正确的参数调用此方法,我得到了正确的答复。但是,如果我使用错误的参数调用它,我的VB6程序中会出现-245757Object reference was not set to an instance of an object)运行时错误,而且它似乎没有被我的C#代码中的catch子句捕获(虽然我希望方法返回一个空的ReplyObject填充Error字段。

我创建了一个测试C#项目并复制了相同的方法(即我在.NET平台中调用相同的Web服务),我可以确认在这种情况下SoapException被正确捕获。< / p>

这种行为是故意的吗?有没有办法在ComVisible类中捕获SoapException(因为我真的想将错误消息包含在我的回复对象中)?

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 个答案:

答案 0 :(得分:0)

(这只是一个猜测,更适合评论,但它很长)

ReplyObject类超出范围时,.NET运行时可能会处理BFRWebServiceconnector COM对象,可能是因为它是类的属性而不是在方法中创建的?

尝试在ReplyObject内创建GetFromBFR,而不是将其作为该类的属性。如果从不同的线程调用COM对象,这也可以防止来自多线程访问的奇怪错误。

如果VB程序中有一条特定的行抛出错误(在你调用GetFromBFR之后),你可以看到VB中的变量是Nothing来尝试缩小问题范围

像我说的那样,只是一个猜测。随意反驳它。 :)

答案 1 :(得分:0)

我非常惭愧,原因非常简单......而不是遵循:

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