无法获得全局错误处理程序来处理我的自托管wcf服务

时间:2012-11-19 09:23:39

标签: c# wcf global ierrorhandler

您好我已经尝试让Ierrorhandler现在工作几个小时而且我很卡住:) 我从本指南中获得了最多的结果

http://www.remondo.net/wcf-global-exception-handling-attribute-and-ierrorhandler/#comment-10385

但我无法使用我的操作/功能

Program.cs的

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;

namespace Phpwcfconsole
{
    class program
    {
        static void Main(string[] args)
        {
            using (ServiceHost host = new ServiceHost(typeof(Service1)))
            {
                try
                {
                    host.Open();
                    Console.WriteLine("Host open. Press any key to <EXIT>");
                    Console.ReadLine();
                    host.Close();
                }
                catch (Exception e)
                {
                    Console.WriteLine(Environment.NewLine + e.Message);
                    host.Close(); 
                }
            }
        }
    }
}

的app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 <system.web>
  <compilation debug="true" />
 </system.web>

 <system.serviceModel>
  <services>
   <service behaviorConfiguration="Phpwcfconsole.Service1Behavior" 
        name="Phpwcfconsole.Service1">
    <endpoint 
      address="" 
      binding="basicHttpBinding" 
      contract="Phpwcfconsole.IService">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
    <host>
      <baseAddresses>
        <add baseAddress="http://agent007:8732/phpwcf/" />
      </baseAddresses>
    </host>
  </service>
</services>
<behaviors>
  <serviceBehaviors>
       <behavior name="Phpwcfconsole.Service1Behavior">
           <serviceMetadata httpGetEnabled="True"/>
           <serviceDebug includeExceptionDetailInFaults="false" />
         </behavior>
       </serviceBehaviors>
     </behaviors>
     <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
     <bindings>
       <basicHttpBinding>
         <binding name="MyServiceBinding"
                hostNameComparisonMode="StrongWildcard"
                receiveTimeout="00:10:00"
                sendTimeout="00:10:00"
                openTimeout="00:10:00"
                closeTimeout="00:10:00"
                maxReceivedMessageSize="20000000"
                maxBufferSize="20000000"
                maxBufferPoolSize="20000000"
                transferMode="Buffered"
                messageEncoding="Text"
                textEncoding="utf-8"
                bypassProxyOnLocal="false"
                useDefaultWebProxy="true" >
           <security mode="None" />
         </binding>
       </basicHttpBinding>
     </bindings>
   </system.serviceModel>
 </configuration>

IService.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;


namespace Phpwcfconsole
{
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        string GetData(int value);
    }
}

Serverfunctions.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace Phpwcfconsole
{
    public partial class Service1 : IService
    {
        public string GetData(int value)
        {
            throw new Exception("error");
        }
    }
}

ExeceptionHandler.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Description;
using System.Collections.ObjectModel;
using System.ServiceModel.Configuration;

namespace Phpwcfconsole
{
    public class GlobalExceptionHandler : IErrorHandler
    {
        public bool HandleError(Exception ex)
        {
            return true;
        }

        public void ProvideFault(Exception ex, MessageVersion version,
                             ref Message msg)
        {
            // Do some logging here

            var newEx = new FaultException(
                string.Format("CALLED FROM YOUR GLOBAL EXCEPTION HANDLER BY {0}",
                              ex.TargetSite.Name));

            MessageFault msgFault = newEx.CreateMessageFault();
            msg = Message.CreateMessage(version, msgFault, newEx.Action);
        }
    }

    public class GlobalExceptionHandlerBehaviourAttribute : Attribute, IServiceBehavior
    {
        private readonly Type _errorHandlerType;

        public GlobalExceptionHandlerBehaviourAttribute(Type errorHandlerType)
        {
            _errorHandlerType = errorHandlerType;
        }

        public void Validate(ServiceDescription description, ServiceHostBase     serviceHostBase)
        {

        }

        public void AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase,
            Collection<ServiceEndpoint> endpoints, BindingParameterCollection parameters)
        {
        }

        public void ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase)
        {
            var handler = (IErrorHandler)Activator.CreateInstance(_errorHandlerType);

            foreach (ChannelDispatcherBase dispatcherBase in serviceHostBase.ChannelDispatchers)
            {
                var channelDispatcher = dispatcherBase as ChannelDispatcher;
                if (channelDispatcher != null)
                channelDispatcher.ErrorHandlers.Add(handler);
            }
        }
    }
}

好吧,如果我把一些console.writeLine放在

公共类GlobalExceptionHandlerBehaviourAttribute:Attribute,IServiceBehavior 功能我看到他们在我启动程序时运行。但是我不能在指南上使用我的函数来举例来抛出异常并让我的IErrorhandler抓住它。

我在其他函数中尝试了一些异常,我的IErrorhandler没有任何反应。

但是我发现到目前为止我发现了一个例外,当我在 Wcftestclient 中添加我的服务然后停止调试并删除 [OperationContract] > IService.cs 然后再次启动并尝试运行该函数而不刷新,该异常被IErrorhandler捕获

所以我的问题是为什么我不能在函数内捕获异常? 非常感谢你的回答。 C(:

1 个答案:

答案 0 :(得分:0)

FaultContractAttribute是否足以满足您的要求? 看一下msdn doc中的示例。 http://msdn.microsoft.com/en-us/library/system.servicemodel.faultcontractattribute.aspx 它听起来与您尝试的相似,复杂性低于自定义服务行为。

在跨流程/机器使用WCF时,FaultContracts相当于异常,因为消费者不一定是.net客户端。