我正在尝试找到一种方法来处理 WCF 路由器中的异常,这意味着当由于任何原因路由器无法将消息发送到主端点(这里有 EndpointNotFoundException、ServerTooBusyException 或 CommunicationObjectFaultedException)并从备份列表中选择一个端点时并将此消息发送到备份端点。如何在路由器服务中获取此内部异常?因为此时我想在内存中动态更改路由器配置,并用主端点更改备份端点。是否可以使用 IErrorHandler 执行此操作?还是可以做这个自定义过滤器?如何使用自定义过滤器更改备份行为?
问问题
615 次
1 回答
0
这是实现 IErrorHandler fo wcf 服务的完整工作示例。我们可以为 WCF 路由器实现这一点,并在路由器级别获取内部异常,然后决定如何在运行时更改配置。
[ServiceContract]
public interface IService1
{
[OperationContract]
[FaultContract(typeof(MyFault))]
string GetData(int value);
}
[DataContract]
public class MyFault
{
}
public class Service1 : IService1
{
public string GetData(int value)
{
throw new Exception("error");
}
}
public class MyErrorHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
return true;
}
public void ProvideFault(Exception error, MessageVersion version, ref Message msg)
{
var vfc = new MyFault();
var fe = new FaultException<MyFault>(vfc);
var fault = fe.CreateMessageFault();
msg = Message.CreateMessage(version, fault, "http://ns");
}
}
public class ErrorHandlerExtension : BehaviorExtensionElement, IServiceBehavior
{
public override Type BehaviorType
{
get { return GetType(); }
}
protected override object CreateBehavior()
{
return this;
}
private IErrorHandler GetInstance()
{
return new MyErrorHandler();
}
void IServiceBehavior.AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
IErrorHandler errorHandlerInstance = GetInstance();
foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
{
dispatcher.ErrorHandlers.Add(errorHandlerInstance);
}
}
void IServiceBehavior.Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ServiceEndpoint endpoint in serviceDescription.Endpoints)
{
if (endpoint.Contract.Name.Equals("IMetadataExchange") && endpoint.Contract.Namespace.Equals("http://schemas.microsoft.com/2006/04/mex"))
continue;
foreach (OperationDescription description in endpoint.Contract.Operations)
{
if (description.Faults.Count == 0)
{
throw new InvalidOperationException("FaultContractAttribute not found on this method");
}
}
}
}
}
网络配置:
<system.serviceModel>
<services>
<service name="ToDD.Service1">
<endpoint address="" binding="basicHttpBinding" contract="ToDD.IService1" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<errorHandler />
</behavior>
</serviceBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add name="errorHandler" type="ToDD.ErrorHandlerExtension, ToDD, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
</system.serviceModel>
因此在 HandleError 方法中,我们可以以适当的方式处理此异常。
于 2012-12-08T14:12:23.683 回答