【发布时间】:2011-07-01 19:30:14
【问题描述】:
我有一些使用 dataContracts 的 WCF 服务,我希望通过 Data 属性中的自定义 Dictionary 数据传递一个异常,但是当我在抛出之前在这个数组上添加任何数据时,我得到以下我的自定义 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();
}
【问题讨论】:
标签: wcf enterprise-library servicecontract faultcontract