dataContracts を使用する WCF サービスがいくつかあり、Data プロパティでカスタム Dictionary< string , object > data を使用して例外を渡したいと思っていましたが、スローする前にこの配列にデータを追加すると、次のエラーが表示されますカスタム ServiceBehavior の ErrorHandler:
Type 'System.Collections.ListDictionaryInternal'
データ コントラクト名 'ArrayOfKeyValueOfanyTypeanyType:http://schemas.microsoft.com/2003/10/Serialization/Arrays' は想定されていません。たとえば、KnownTypeAttribute 属性を使用するか、DataContractSerializer に渡される既知の型のリストにそれらを追加することにより、静的に認識されていない型を既知の型のリストに追加します。
DataContract として注釈が付けられた Dictionary プロパティを使用してカスタム例外を常に作成し、それをスローする必要がありますか? ErrorHandler を使用するという考えは、各サービス メソッドで例外を処理することを回避することですが、メソッドにさらに注釈を追加する必要がありますか? 私は何が欠けていますか?
参考までに、これは私の FaultErrorHandler クラスです。
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)
{
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();
}
}
私の典型的なサービスインターフェースは次のようになります:
[ServiceContract(Name = "Service", Namespace = Schema.WebServiceStandard, SessionMode = SessionMode.Allowed)]
public interface IService
{
[OperationContract(Name = "GetSomething")]
[FaultContract(typeof(ValidationFault))]
LookupResult GetSomething();
}