1

古い VB6 クラスで呼び出される .NET で ComVisible ライブラリを開発しています。クラスで基本的に行うことは、Web サービスを呼び出し、応答を解析し、必要なデータを含むオブジェクトを返すことです。SoapExceptionWeb サービスは、間違ったパラメーターで呼び出された場合に を返すように設計されています。ここに私のコードの一部があります:

    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 プログラムで-245757( ) ランタイム エラーが発生し、C# コードの句でキャッチされていないように見えます (ただし、メソッドによって空のフィールドが返されることを期待します)。 .Object reference was not set to an instance of an objectcatchReplyObjectError

テスト C# プロジェクトを作成し、同じメソッドをコピーしました (つまり、.NET プラットフォーム内から同じ Web サービスを呼び出します)。この場合、SoapExceptionが適切にキャッチされていることを確認できます。

この動作は意図的なものですか? 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
4

2 に答える 2

0

(これは単なる推測であり、コメントに適していますが、かなり長いです)

クラスがスコープ外になったときに、.NET ランタイムがReplyObjectCOM オブジェクトを破棄している可能性がありますBFRWebServiceconnector。これは、おそらくそれがクラスのプロパティであり、メソッド内で作成されていないためですか?

クラスのプロパティにする代わりに、ReplyObject内に作成してみてください。GetFromBFRこれにより、COM オブジェクトが異なるスレッドから呼び出された場合に、マルチスレッド アクセスによる奇妙なエラーを防ぐこともできます。

また、VB プログラムにエラーをスローしている特定の行がある場合 ( を呼び出した後GetFromBFR)、変数が VB 内にあるかどうかを確認Nothingして、問題を絞り込むことができます。

私が言ったように、ただの推測です。遠慮なく反論してください。:)

于 2013-01-04T15:08:09.117 に答える
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が判明しました...nullNullPointerException

于 2013-01-07T16:02:30.677 に答える