IErrorHandler不';我似乎没有处理我在WCF中的错误。。有什么想法吗?
一直在阅读IErrorHandler的相关信息,并希望转到配置路径。 因此,为了实现它,我阅读了以下内容 这基本上只是包装在继承IErrorHandler和IServiceBehaviour的类中的msdn示例。。。然后将其包装在继承自BehaviorExtensionElement的扩展元素中,以允许我将该元素添加到web.config中。我错过了什么 我已经编译了它,从我修复的各种错误来看,似乎WCF实际上正在加载错误处理程序。我的问题是,我要在错误处理程序中处理的异常不存在;无法将异常传递给它 我的服务实现只是在另一个类上调用一个抛出ArgumentOutOfRangeException的方法,但是这个异常永远不会被处理程序处理 我的web.configIErrorHandler不';我似乎没有处理我在WCF中的错误。。有什么想法吗?,wcf,ierrorhandler,Wcf,Ierrorhandler,一直在阅读IErrorHandler的相关信息,并希望转到配置路径。 因此,为了实现它,我阅读了以下内容 这基本上只是包装在继承IErrorHandler和IServiceBehaviour的类中的msdn示例。。。然后将其包装在继承自BehaviorExtensionElement的扩展元素中,以允许我将该元素添加到web.config中。我错过了什么 我已经编译了它,从我修复的各种错误来看,似乎WCF实际上正在加载错误处理程序。我的问题是,我要在错误处理程序中处理的异常不存在;无法将异
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basic">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<extensions>
<behaviorExtensions>
<add name="customHttpBehavior"
type="ErrorHandlerTest.ErrorHandlerElement, ErrorHandlerTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
<behaviors>
<serviceBehaviors>
<behavior name="exceptionHandlerBehaviour">
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="true"/>
<customHttpBehavior />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="exceptionHandlerBehaviour" name="ErrorHandlerTest.Service1">
<endpoint binding="basicHttpBinding" bindingConfiguration="basic" contract="ErrorHandlerTest.IService1" />
</service>
</services>
ErrorHandler类
public class ErrorHandler : IErrorHandler , IServiceBehavior
{
public bool HandleError(Exception error)
{
Console.WriteLine("caught exception {0}:",error.Message );
return true;
}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
if (fault!=null )
{
if (error is ArgumentOutOfRangeException )
{
var fe = new FaultException<GeneralInternalFault>(new GeneralInternalFault("general internal fault."));
MessageFault mf = fe.CreateMessageFault();
fault = Message.CreateMessage(version, mf, fe.Action);
}
else
{
var fe = new FaultException<GeneralInternalFault>(new GeneralInternalFault(" the other general internal fault."));
MessageFault mf = fe.CreateMessageFault();
fault = Message.CreateMessage(version, mf, fe.Action);
}
}
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
IErrorHandler errorHandler = new ErrorHandler();
foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
{
ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
if (channelDispatcher != null)
{
channelDispatcher.ErrorHandlers.Add(errorHandler);
}
}
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
}
您可以通过向ApplyDispatchBehavior添加一个打印或断点来查看web.config是否正在工作和加载,并查看该服务首次打开时是否打印/命中。那么它正在加载吗
我还要在默认设置下添加一个打印/断点。下面是一个完整的工作示例:
[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");
}
}
}
}
}
[服务合同]
公共接口IService1
{
[经营合同]
[FaultContract(类型(MyFault))]
字符串GetData(int值);
}
[数据合同]
公共类MyFault
{
}
公共类服务1:IService1
{
公共字符串GetData(int值)
{
抛出新异常(“错误”);
}
}
公共类MyErrorHandler:IErrorHandler
{
公共布尔句柄错误(异常错误)
{
返回true;
}
public void providefaulture(异常错误,MessageVersion,ref Message msg)
{
var vfc=新的MyFault();
var fe=新故障异常(vfc);
var fault=fe.CreateMessageFault();
msg=Message.CreateMessage(版本,错误,“http://ns");
}
}
公共类ErrorHandlerExtension:BehaviorExtensionElement,IServiceBehavior
{
公共重写类型BehaviorType
{
获取{return GetType();}
}
受保护的重写对象CreateBehavior()
{
归还这个;
}
私有IErrorHandler GetInstance()
{
返回新的MyErrorHandler();
}
void IServiceBehavior.AddBindingParameters(ServiceDescription ServiceDescription,ServiceHostBase ServiceHostBase,集合终结点,BindingParameterCollection bindingParameters)
{
}
无效IServiceBehavior.ApplyDispatchBehavior(ServiceDescription ServiceDescription,ServiceHostBase ServiceHostBase)
{
IErrorHandler errorHandlerInstance=GetInstance();
foreach(serviceHostBase.ChannelDispatchers中的ChannelDispatcher)
{
dispatcher.ErrorHandlers.Add(errorHandlerInstance);
}
}
无效IServiceBehavior.Validate(ServiceDescription ServiceDescription,ServiceHostBase ServiceHostBase)
{
foreach(serviceDescription.Endpoints中的ServiceEndpoint端点)
{
if(endpoint.Contract.Name.Equals(“IMetadataExchange”)&&
endpoint.Contract.Namespace.Equals(“http://schemas.microsoft.com/2006/04/mex"))
继续;
foreach(endpoint.Contract.Operations中的操作描述)
{
如果(description.Faults.Count==0)
{
抛出新的InvalidOperationException(“在此方法上未找到FaultContractAttribute”);
}
}
}
}
}
和web.config:
<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>
断点不会被击中。我能找到的唯一断点是Web服务本身。非常感谢,很抱歉,我花了这么长时间才回答,我的工作设置已经没有了。不过,这在我的家庭设置中运行良好。虽然visual studio抱怨“元素行为具有无效的子元素errorhandler”,但对我来说仍然有效-我只是忽略了它,并且在运行时它可以工作。如何使它返回自定义类型的json对象(例如MyFault)?下面是如何使它返回json:
[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>