뭔가 잘못되면 일반적인 FaultException을 throw하는 WCF 서비스가 있습니다. 이유를 모르겠다. 때로는 클라이언트가 제네릭 예외 대신 일반이 아닌 FaultException을 잡을 수 있습니다.일반적인 FaultException을 던지고
아무도 모르는가, 문제는 무엇입니까?
뭔가 잘못되면 일반적인 FaultException을 throw하는 WCF 서비스가 있습니다. 이유를 모르겠다. 때로는 클라이언트가 제네릭 예외 대신 일반이 아닌 FaultException을 잡을 수 있습니다.일반적인 FaultException을 던지고
아무도 모르는가, 문제는 무엇입니까?
서비스에서 모든 예외를 처리하고 FaultException에 랩핑해야합니다. <T> 여기서 T는 작성한 데이터 계약입니다. 그래서 첫 번째 단계는 예외 정보를 포함하는 사용자 정의 데이터 계약을 정의하는 것입니다 :
[DataContract]
public class CustomFault
{
public string Message { get; set; }
}
그런 다음 당신은 그것의 방법은 잠재적 오류 예외 <CustomFault>을 던질 수있는 서비스 계약을 지시합니다.
public class MyService : IMyServiceContract
{
public void MyMethod(string someArgument)
{
// Do something here that could throw exceptions but don't catch yet
}
}
당신이 구현할 수있는 예외를 처리하려면 다음
[ServiceContract]
public interface IMyServiceContract
{
[FaultContract(typeof(CustomFault))]
void MyMethod(string someArgument);
}
다음 단계는이 인터페이스를 구현하는 것입니다 : 이것은 클라이언트가 프록시 클래스를 생성 할 수 있도록 WSDL에 CustomFault 클래스를 노출하는 서비스를 할 수 있습니다 IErrorHandler은 서비스 메소드 중 하나가 예외를 throw 할 때마다 사용됩니다. 이 오류 처리기의 목적은 오류 예외 <CustomFault>에 예외를 래핑하는 것입니다 :
클라이언트 측에서, 당신의 오류 처리기를 등록하면public class MyErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
return true;
}
public void ProvideFault(Exception error, MessageVersion version, ref Message msg)
{
var customFault = new CustomFault()
{
Message = error.Message,
};
var fe = new FaultException<CustomFault>(customFault);
MessageFault fault = fe.CreateMessageFault();
string ns = "http://somenamespace/whatever";
msg = Message.CreateMessage(version, fault, ns);
}
}
, 당신은 항상 오류 예외 <CustomFault>을 얻을 것이다.
서비스가 캐치되지 않은 다른 예외를 throw하면 비표준 FaultException
이 발생합니다. 예외가 무엇인지 알아 내서 버그 일 경우 수정하거나 클라이언트를 공개하려는 것으로 결정한 다음 일반 FaultException
에 포장하고 FaultContract
을 적절하게 추가해야합니다.
다른 가능성은 TDetail이 제대로 직렬화되지 않는 것입니다. 예를 들어, TDetail은 Exception에서 파생되며 직렬화 할 수없는 내부 예외가 있습니다.
클라이언트가 예외 유형 자체 (< T>가 FaultException < T>)에 액세스 할 수없는 경우 FaultException의 일반이 아닌 버전이 발생합니다. 나는 이것을 알아 내려고 애쓰는 데 몇 시간을 보냈고, 결국 msdn 포럼에서 this을 발견했을 때 깨달았다. 예외가 서비스 밖으로 던지기 전에 변경되었다는 표시가 있으면 좋겠지 만 그렇지 않습니다.
나는 분명하지 않을 수도 있습니다. 나는 scope visibility와 관련하여 access라는 단어를 사용했다. 예를 들어 예외가 클라이언트 외부에서 정의되고 FaultContract 속성을 사용하는 서비스 호출에 표시되지 않으면 클라이언트가 Exception에 액세스 할 수 없기 때문에 다운 변환이 발생합니다. – Drew
FaultContractAttribute를 사용하여 오류 세부 정보 유형을 선언하지 않은 경우 발생합니다.
[ServiceContract]
public interface IMyServiceContract
{
//...
[OperationContract]
[FaultContract(typeof(MyFaultDetail))]
[FaultContract(typeof(OtherFaultDetail))]
GetDetailsResp GetDetails(GetDetailsReq req);
//...
}
저도 같은 문제와 링크 드류가 나에게 답을 제공 게시 된보고 있었다 : 여기
은 서비스 계약이 보일 것입니다 방법이다.
해결 방법은 내 서비스 인터페이스가 내 서비스 오류와 다른 네임 스페이스를 사용한다는 것입니다.
[ServiceContract(Namespace = "http://dummydomain.com/service/searchservice")]
public interface ISearchService
....
와 서비스 오류가 있었다 :
즉, 서비스 계약했다
[DataContract(Namespace = "http://dummydomain.com/service/searchservicefault")]
public class MySearchServiceFault
...
네임 스페이스 클라이언트가 그것으로 무엇을 해야할지하지 않는 다른 외관상 때갑니다 다시 비 일반 FaultContract ... 나는 위의 코드가 작동하고 일반적인 FaultContract를 반환하는 것으로 보아 클라이언트에 다소 의존한다고 생각합니다.
하지만 내가 네임 스페이스가 동일하게 변경되었습니다. 테스트에서 코드가 항상 작동하도록 만드는 것 같습니다.
wierd는 동일한 예외이며, 때로는 제네릭이 아닌 FaultException으로 throw됩니다. – mrtaikandi