나는이 모든 것을 읽었 습니다만, 어쩌면 나는 뭔가를 놓치고 있습니다. (물론, 그렇지 않다면 이미 작동하지 않을 것입니다)클라이언트는 일반 FaultException을 catch하지 않을 것입니다 < T >, FaultException 만
내 서버 비즈니스 계층 내부에서 일부 예외 오류를 던지고있어 : 나는 서비스에서 처리되지 않은 떠나지 만, 내가 IErrorHandler
이
public class RfcException : Exception
{
public RfcException(string _m, Exception _inner) : base(_m, _inner)
{ }
public Dictionary<string, string> ExtendedProperties
{
get { return extendedProperties; }
protected set { extendedProperties = value; }
}
private Dictionary<string, string> extendedProperties = new Dictionary<string, string>();
}
가 잡아 만들 FaultMessage
:
public class FaultErrorHandler : BehaviorExtensionElement, IErrorHandler, IServiceBehavior
{
public bool HandleError(Exception error)
{
if (!Logger.IsLoggingEnabled()) return true;
var logEntry = new LogEntry
{
EventId = 100,
Severity = TraceEventType.Error,
Priority = 1,
Title = "WCF Failure",
Message = string.Format("Error occurred: {0}", error)
};
logEntry.Categories.Add("MiddleTier");
Logger.Write(logEntry);
return true;
}
public void ProvideFault(Exception error, System.ServiceModel.Channels.MessageVersion version, ref System.ServiceModel.Channels.Message fault)
{
if (error is RfcException)
{
RfcException rfcException = error as RfcException;
var serviceFault = new RfcServiceFault(rfcException);
var faultException = new FaultException<RfcServiceFault>(serviceFault, new FaultReason(string.Format("System error occurred, exception: {0}", error)));
var faultMessage = faultException.CreateMessageFault();
fault = Message.CreateMessage(version, faultMessage, Schema.WebServiceStandard);
}
else
{
var faultException = new FaultException<Exception>(error, new FaultReason(string.Format("System error occurred, exception: {0}", error)));
var faultMessage = faultException.CreateMessageFault();
fault = Message.CreateMessage(version, faultMessage, Schema.WebServiceStandard);
}
}
public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{ }
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher chanDisp in serviceHostBase.ChannelDispatchers)
{
chanDisp.ErrorHandlers.Add(this);
};
}
public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
{ }
public override Type BehaviorType
{
get { return typeof(FaultErrorHandler); }
}
protected override object CreateBehavior()
{
return new FaultErrorHandler();
}
}
요청할 필요가 없습니다. 이미 디버거를 사용하여 부품 번호 if (error is RfcException)
에 입력했음을 확인했습니다.이 코드를 통해 단계적으로 진행되었으므로 문제없이 끝까지 도달합니다. 이제
[ServiceContract(Name = "MyService", Namespace = Schema.WebServiceStandard, SessionMode = SessionMode.Allowed)]
public interface IMyService
{
[OperationContract(Name = "GetStuff")]
[FaultContract(typeof(RfcServiceFault) , Name="RfcServiceFault", Namespace="Service.DataTransfer.Rfc")]
LookupResult GetStuff();
}
을 : ErrorHandler를가 FaultException<RfcServiceFault>
메시지를 래핑 는 RfcServiceFault
메시지 서비스는 faultContract와 WCF 서비스를해야하는 모든 주석을 가지고이
[DataContract(Name = "RfcServiceFault", Namespace = "Service.DataTransfer.Rfc")]
public class RfcServiceFault
{
public RfcServiceFault(RfcException rfcException) : this((Exception)rfcException)
{
ExtendedProperties = new Dictionary<string, string>(rfcException.ExtendedProperties);
}
public RfcServiceFault()
{ }
public RfcServiceFault(Exception regularException)
{
FaultMessage = regularException.Message;
StackTrace = regularException.StackTrace;
}
public Dictionary<string, string> ExtendedProperties
{
get { return extendedProperties; }
protected set { extendedProperties = value; }
}
[DataMember]
private Dictionary<string, string> extendedProperties = new Dictionary<string, string>();
[DataMember]
public string FaultMessage { get; set; }
[DataMember]
public string StackTrace { get; set; }
}
인에서 테스트 클라이언트, 다음과 같은 간단한 테스트 :
try
{
var result = myService.GetStuff();
Assert.IsTrue(!string.IsNullOrEmpty(result));
}
catch (FaultException<RfcServiceFault> rfcEx)
{
// OMG FOR THE LIFE OF THE PUPPIES ENTER HERE
}
catch (FaultException rr)
{
// it always falls in here
}
catch (Exception ex)
{ }
나는 많은 것을 읽었으며, 이 유사한 문제에 대한 많은 게시물 :
- Cannot handle FaultException
- Throwing generic FaultException
- c# WCF catch Fault Exceptions of Base type
- WCF: WSDL-first approach: Problems with generating fault types
하지만 아무것도 지금까지 내가 추적을 WCF를 설정하려고했습니다 도움이 보인다 Web.config의 :
<system.diagnostics>
<sources>
<source name="System.ServiceModel"
switchValue="Information, ActivityTracing">
<listeners>
<add name="log"
type="System.Diagnostics.XmlWriterTraceListener"
initializeData="c:\Traces.svclog" />
</listeners>
</source>
</sources>
</system.diagnostics>
하고 내가 거기에 svclog 파일을 얻을, 나는 WCF 추적 뷰어로 열고,하지만 난 단지, 노란색 하나는 예외를 보여 메시지의 무리를 볼 수 있지만, 그것은 단지 클라이언트가 이미 System.ServiceModel.FaultException
,보고되어 수신되는 것을 확인 오히려 일반적인 하나
어떤 아이디어보다이 문제를 파악하는 방법?
편집 내가 이렇게 설정 내 오류 처리기를 활성화 언급하는 것을 잊었다 :
<behaviorExtensions>
.....
<add name="faultErrorHandlerBehavior"
type="Service.FaultErrorHandler,Service, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
.....
</behaviorExtensions>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceThrottling maxConcurrentCalls="200" maxConcurrentSessions="200"
maxConcurrentInstances="200" />
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
<faultErrorHandlerBehavior />
</behavior>
</serviceBehaviors>
을 당신이 한 번에 너무 많은 문제를 해결하기 위해 노력하고있다 – lurscher
서비스 오류에서 사전 속성을 주석 시도 할 것이다. IErrorHandler를 제거하고 단순히 string을 제외한 추가 속성없이 새로운 CustomFault를 사용할 수 있습니까? –
@Henk 사전을 제거하지 않는 것이 상황을 개선하는 것처럼 보입니다 – lurscher