Как настроить web.config для WCF IErrorhandler
Не могу интегрировать IErrorHandler в мой проект с правильным web.config
У меня есть успешно работающий WCF, который используется веб-клиентами в.net 4, но при попытке настроить IErrorhandler в качестве глобального регистратора ошибок в качестве всеохватывающего метода для всех моих сервисных методов, все происходит быстро, в основном из-за части web.config! Пожалуйста помоги.
Три службы: IReport, IServiceCustomer, IServiceUser
Реализовал IErrorHandler в отдельном классе с именем MyErrorClass.cs следующим образом:
namespace CustomerWcfService
{
public class WcfErrorHandler : IErrorHandler
{
/// <summary>
/// Enables the creation of a custom <see cref="T:System.ServiceModel.FaultException`1"/> that is returned from an exception in the course of a service method.
/// </summary>
/// <param name="error">The <see cref="T:System.Exception"/> object thrown in the course of the service operation.</param><param name="version">The SOAP version of the message.</param><param name="fault">The <see cref="T:System.ServiceModel.Channels.Message"/> object that is returned to the client, or service, in the duplex case.</param>
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
// can create custom error messages here
}
/// <summary>
/// Enables error-related processing and returns a value that indicates whether the dispatcher aborts the session and the instance context in certain cases.
/// </summary>
/// <returns>
/// true if should not abort the session (if there is one) and instance context if the instance context is not <see cref="F:System.ServiceModel.InstanceContextMode.Single"/>; otherwise, false. The default is false.
/// </returns>
/// <param name="error">The exception thrown during processing.</param>
public bool HandleError(Exception error)
{
// log error to database using legacy error handler
ErrorHandler.LogError(error);
// Let the other ErrorHandler do their jobs
return true;
}
}
public class WcfErrorServiceBehaviour : IServiceBehavior
{
/// <summary>
/// Provides the ability to inspect the service host and the service description to confirm that the service can run successfully.
/// </summary>
/// <param name="serviceDescription">The service description.</param><param name="serviceHostBase">The service host that is currently being constructed.</param>
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{ }
/// <summary>
/// Provides the ability to pass custom data to binding elements to support the contract implementation.
/// </summary>
/// <param name="serviceDescription">The service description of the service.</param><param name="serviceHostBase">The host of the service.</param><param name="endpoints">The service endpoints.</param><param name="bindingParameters">Custom objects to which binding elements have access.</param>
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{ }
/// <summary>
/// Provides the ability to change run-time property values or insert custom extension objects such as error handlers, message or parameter interceptors, security extensions, and other custom extension objects.
/// </summary>
/// <param name="serviceDescription">The service description.</param><param name="serviceHostBase">The host that is currently being built.</param>
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
var handler = new WcfErrorHandler();
foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
{
dispatcher.ErrorHandlers.Add(handler);
}
}
}
public class WcfErrorHandlerBehaviour : BehaviorExtensionElement
{
/// <summary>
/// Creates a behavior extension based on the current configuration settings.
/// </summary>
/// <returns>
/// The behavior extension.
/// </returns>
protected override object CreateBehavior() { return new WcfErrorServiceBehaviour(); }
/// <summary>
/// Gets the type of behavior.
/// </summary>
/// <returns>
/// A <see cref="T:System.Type"/>.
/// </returns>
public override Type BehaviorType { get { return typeof (WcfErrorServiceBehaviour); } }
}
}
Как должен выглядеть файл web.config, когда я перепробовал миллион комбинаций из различных уроков и ответов в сети, но это не помогло! Вот как выглядит оригинальный рабочий фрагмент файла web.config, когда я не использую IErrorHandler
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<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" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
Пожалуйста, может кто-нибудь отправить этот WCF noob исправленный web.config, пожалуйста, так как я продолжаю удалять и пробовать снова и не получаю (я потерял так много дней на этом):(
2 ответа
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<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" />
<errorHandler/>
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
<extensions>
<behaviorExtensions>
<add name="errorHandler" type="CustomerWcfService.WcfErrorHandlerBehaviour, CustomerWcfService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</behaviorExtensions>
</extensions>
</system.serviceModel>
А затем примените свое поведение к службе, к которой вы хотите применить его.
Редактировать:
извините за промах, но вам действительно нужно удалить любой разрыв строки и любые дополнительные пробелы в имени типа в определении расширения (старая ошибка WCF, которая вынуждает вас использовать полностью определенную строку имени в объявлении типа расширения).
Это немного поздно, но для других пользователей здесь лучший подход (на мой взгляд), и приведенный выше код нужно только немного изменить
Ты можешь измениться:
public class WcfErrorServiceBehaviour : IServiceBehavior
чтобы:
public class WcfErrorServiceBehaviourAttribute : Attribute, IServiceBehavior
Теперь вы можете использовать это как атрибут для вашего класса обслуживания, например:
[WcfErrorServiceBehaviour]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,
ConcurrencyMode = ConcurrencyMode.Multiple)]
public class MXServiceCommands : IMXServiceCommands
{
}
Надеюсь, это поможет другим.