2013-01-04 5 views
1

.NET에서 ComVisible 라이브러리를 개발 중이며 이전 VB6 클래스에서 호출됩니다. 기본적으로 클래스에서 수행하는 작업은 응답을 파싱하고 필요한 데이터가있는 객체를 반환하는 웹 서비스를 호출하는 것입니다. 잘못된 매개 변수로 호출 된 경우 SoapException을 반환하도록 웹 서비스가 설계되었습니다. SoapException이 ComVisible 클래스에서 catch되지 않았습니다.

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 코드에서이 메소드를 호출하려고하면

, 나는 적절한 대답을 얻을 : 여기 내 코드의 일부이다. 하지만 잘못된 매개 변수를 호출하면 VB32 프로그램에서 -245757 ( Object reference was not set to an instance of an object) 런타임 오류가 발생하고 이 채워진 Error 필드가있는 반면 내 C# 코드에서는 catch 절에 의해 캐치되지 않는 것으로 보입니다 메서드에서 반환 됨).

테스트 C# 프로젝트를 만들고 동일한 방법 (예 : .NET 플랫폼 내에서 동일한 웹 서비스를 호출 함)을 복사했으며이 경우 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 
+0

catch 절에 오류가 설정되어있는 동안 _replay 개체가 초기화되지 않았을 수 있습니다. _reply.Error = "Error :"Error : "+ ex.Message;' – Algirdas

+0

@algirdas, 아니요, 생성자에서 초기화됩니다. – Azimuth

+0

VB의 런타임 오류는 무엇입니까? –

답변

0

나는 대신에 다음과 ... 이유는 아주 아주 간단한 것을 매우 부끄러워 해요 : 그것은 밝혀

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 
    } 

과 :

catch (Exception ex) 
    { 
     _reply.Error = "Error: " + ex.Message; 
     if (_client.InnerChannel.State == CommunicationState.Faulted) _client = new WCFPersonClient("WSHttpBinding_IWCFPerson"); //recreate the failed channel 
    } 

실제로 코드를 다음했다 ex.InnerExceptionnull이고 NullPointerException ...

0

(이것은 단지 추측과 의견에 더 맞는이지만 꽤 길다)

그것은 .NET 런타임이 폐기되는 것을 가능 COM 개체의 경우 BFRWebServiceconnector 클래스가 범위를 벗어날 때, 클래스의 속성이며 메서드 내에서 만들어지지 않았기 때문일 수 있습니다.

ReplyObjectGetFromBFR 내에 만들어 클래스의 속성으로 사용하는 것이 좋습니다. 또한 COM 객체가 다른 스레드에서 호출되면 다중 스레드 액세스의 이상한 오류를 방지 할 수 있습니다.

VB 프로그램에서 오류가 발생하는 특정 줄 (예 : GetFromBFR)이 있으면 VB에서 변수가 Nothing인지 확인하여 문제의 범위를 좁힐 수 있습니다.

내가 말했듯이, 그냥 추측합니다. 자유롭게 그것을 반박하십시오. :)

+0

메소드 내에서'ReplyObject'를 만들려고합니다. 어떻게 든 나는이 점을 나 자신으로 놓쳤다. .. – Azimuth

+0

나는 도와주지 않았다. 나는 여전히 같은 오류가 발생합니다. – Azimuth