<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      利用Attribute和IErrorHandler處理WCF全局異常

      在處理WCF異常的時(shí)候,有大概幾種方式:

      第一種是在配置文件中,將includeExceptionDetailInFaults設(shè)置為true

      <behavior name="serviceDebuBehavior"><serviceDebug includeExceptionDetailInFaults="true" /></behavior>
      但是這種方式會(huì)導(dǎo)致敏感信息泄漏的危險(xiǎn),一般我們僅僅在調(diào)試的時(shí)候才開(kāi)啟該屬性,如果已經(jīng)發(fā)布,為了安全,我們一般會(huì)設(shè)置成false。

      第二種方法是自定義錯(cuò)誤,通過(guò)FaultException直接指定錯(cuò)誤信息。

      [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
      public class CalculatorService : ICalculator
      {
      throw new FaultException("被除數(shù)y不能為零!");
      }
      但這樣我們還必須為WCF的方法里顯式的去拋出異常,如果能像.NET一樣,在Global里直接捕獲全局的異常,并寫(xiě)入log4net日志多好,有沒(méi)有方法在wcf里如果出現(xiàn)異常,異常日志寫(xiě)入服務(wù)器斷,同時(shí)拋給客戶(hù)端呢?

      要實(shí)現(xiàn)這個(gè),需要三步

      第一步: 我們需要實(shí)現(xiàn)IErrorHandler接口,實(shí)現(xiàn)他的兩個(gè)方法

      bool HandleError(Exception error);
      void ProvideFault(Exception error, MessageVersion version, ref Message fault);

      其中HandleError是true表示終止當(dāng)前session

      在ProvideFault方法里我們可以寫(xiě)我們要拋給客戶(hù)端的自定義的錯(cuò)誤,同時(shí)也可以在服務(wù)器端寫(xiě)異常日志。

      我們實(shí)現(xiàn)一個(gè)GlobalExceptionHandler ,繼承自IErrorHandler,同時(shí)在ProvideFault里通過(guò)log4net寫(xiě)服務(wù)器端日志,如下:

       

      namespace WcfService

      {
          using System;
          using System.ServiceModel;
          using System.ServiceModel.Channels;
          using System.ServiceModel.Dispatcher;

          /// <summary>
          /// GlobalExceptionHandler
          /// </summary>
          public class GlobalExceptionHandler : IErrorHandler
          {
              /// <summary>
              /// 測(cè)試log4net
              /// </summary>
              private static readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(GlobalExceptionHandler));

              #region IErrorHandler Members
              /// <summary>
              /// HandleError
              /// </summary>
              /// <param name="ex">ex</param>
              /// <returns>true</returns>
              public bool HandleError(Exception ex)
              {
                  return true;
              }

              /// <summary>
              /// ProvideFault
              /// </summary>
              /// <param name="ex">ex</param>
              /// <param name="version">version</param>
              /// <param name="msg">msg</param>
              public void ProvideFault(Exception ex, MessageVersion version, ref Message msg)
              {
                  //// 寫(xiě)入log4net
                  log.Error("WCF異常", ex);
                  var newEx = new FaultException(string.Format("WCF接口出錯(cuò) {0}", ex.TargetSite.Name));
                  MessageFault msgFault = newEx.CreateMessageFault();
                  msg = Message.CreateMessage(version, msgFault, newEx.Action);
              }
              #endregion
          }
      }

      第二步:現(xiàn)在我們需要?jiǎng)?chuàng)建一個(gè)自定義的Service Behaviour Attribute,讓W(xué)CF知道當(dāng)WCF任何異常發(fā)生的時(shí)候,我們通過(guò)這個(gè)自定義的Attribute來(lái)處理。實(shí)現(xiàn)這個(gè)需要繼承IServiceBehavior接口,并在此類(lèi)的構(gòu)造函數(shù)里,我們獲取到錯(cuò)誤類(lèi)型。

      一旦ApplyDispatchBehavior行為被調(diào)用時(shí),我們通過(guò)Activator.CreateInstance創(chuàng)建錯(cuò)誤handler,并把這個(gè)錯(cuò)誤添加到每個(gè)channelDispatcher中。

      ApplyDispatchBehavior

      channelDispatcher中文叫信道分發(fā)器,當(dāng)我們的ServiceHost調(diào)用Open方法,WCF就會(huì)創(chuàng)建我們的多個(gè)信道分發(fā)器(ChannelDispatcher),每個(gè)ChannelDispatcher都會(huì)擁有一個(gè)信道監(jiān)聽(tīng)器(ChannelListener),ChannelListener就有一直在固定的端口監(jiān)聽(tīng),等到Message的到來(lái),調(diào)用AcceptChannel構(gòu)建信道形成信道棧,開(kāi)始對(duì)Message的處理。

      using System;
      using System.Collections.ObjectModel;
      using System.ServiceModel;
      using System.ServiceModel.Channels;
      using System.ServiceModel.Description;
      using System.ServiceModel.Dispatcher;
       
      namespace WcfService
      {
          public class GlobalExceptionHandlerBehaviourAttribute : Attribute, IServiceBehavior
          {
              private readonly Type _errorHandlerType;
       
              public GlobalExceptionHandlerBehaviourAttribute(Type errorHandlerType)
              {
                  _errorHandlerType = errorHandlerType;
              }
       
              #region IServiceBehavior Members
       
              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);
                  }
              }
       
              #endregion
          }
      }

      第三步:在我們的WCF的類(lèi)上,加上GlobalExceptionHandlerBehaviour

      using System;
       
      namespace WcfService
      {
          [GlobalExceptionHandlerBehaviour(typeof (GlobalExceptionHandler))]
          public class SomeService : ISomeService
          {
              #region ISomeService Members
       
              public string SomeFailingOperation()
              {
                  throw new Exception("Kaboom");
                  return null;
              }
       
              #endregion
          }
      }
      這時(shí)候,客戶(hù)端和服務(wù)器端都已經(jīng)分別能記錄到錯(cuò)誤的異常日志了。
      附:log4net配置

      <?xml version="1.0" encoding="utf-8" ?>
      <configuration>
      <configSections>
        <section name="log4net"
                  type="log4net.Config.Log4NetConfigurationSectionHandler, log4net, Version=1.2.10.0, Culture=Neutral, PublicKeyToken=bf100aa01a5c2784" />
      </configSections>
       
      <log4net>
        <!-- 日志文件部分log輸出格式的設(shè)定 -->
        <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
          <file value="./Logs\Log_" />
          <appendToFile value="true" />
          <rollingStyle value="Date" />
          <datePattern value="yyyyMMdd'.txt'" />
          <staticLogFileName value="false" />
          <layout type="log4net.Layout.PatternLayout">
            <header value="------------------------------------------------------------&#xD;&#xA;" />
            <ConversionPattern value="%date [%thread] %-5level %logger [%ndc] - %message%newline%newline%newline" />
          </layout>
        </appender>

        <appender name="WcfService.Api_Error" type="log4net.Appender.RollingFileAppender" LEVEL="ERROR">
          <file value="./Logs\API\logError_" />
          <appendToFile value="true" />
          <datePattern value="yyyyMMdd'.txt'" />
          <rollingStyle value="Date" />
          <staticLogFileName value="false" />
          <layout type="log4net.Layout.PatternLayout">
            <header value="[Header]&#13;&#10;" />
            <footer value="[Footer]&#13;&#10;" />
            <conversionPattern value="%date{dd/MM/yyyy-HH:mm:ss} %m%newline%exception" />
          </layout>
          <filter type="log4net.Filter.LevelRangeFilter">
            <param name="LevelMin" value="ERROR" />
            <param name="LevelMax" value="ERROR" />
          </filter>
        </appender>

        <appender name="WcfService.Api_Info" type="log4net.Appender.RollingFileAppender" LEVEL="INFO">
          <file value="./Logs\API\logInfo_" />
          <appendToFile value="true" />
          <datePattern value="yyyyMMdd'.txt'" />
          <rollingStyle value="Date" />
          <staticLogFileName value="false" />
          <layout type="log4net.Layout.PatternLayout">
            <header value="[Header]&#13;&#10;" />
            <footer value="[Footer]&#13;&#10;" />
            <conversionPattern value="%date{dd/MM/yyyy-HH:mm:ss} %m%newline%exception" />
          </layout>
          <filter type="log4net.Filter.LevelRangeFilter">
            <param name="LevelMin" value="INFO" />
            <param name="LevelMax" value="INFO" />
          </filter>
        </appender>
       
        <root>
          <level value="All" />
          <appender-ref ref="RollingLogFileAppender" />
        </root>

        <logger name="WcfService" additivity="false">
          <appender-ref ref="WcfService.Api_Info" />
          <appender-ref ref="WcfService.Api_Error" />
        </logger>
      </log4net>
      </configuration>

       
      posted @ 2012-10-26 18:27  趙學(xué)智  閱讀(4967)  評(píng)論(7)    收藏  舉報(bào)
      主站蜘蛛池模板: 亚洲欧美日韩综合在线丁香| 一区二区丝袜美腿视频| 国产精品中文字幕av| 大地资源网中文第五页| 亚洲午夜福利精品无码不卡| 诏安县| 99国产精品一区二区蜜臀| 天天澡日日澡狠狠欧美老妇| 小金县| 久播影院无码中文字幕| 国产成人亚洲老熟女精品| 免费午夜无码片在线观看影院| 国产成人综合色就色综合| 国产永久免费高清在线观看| 久久综合亚洲鲁鲁九月天| 亚洲综合日韩av在线| 男人扒开添女人下部免费视频| 亚洲av日韩av永久无码电影| 欧洲lv尺码大精品久久久| 久久综合综合久久高清免费| 亚洲av二区国产精品| 中文幕无线码中文字夫妻| 国产又爽又黄又无遮挡的激情视频 | 精品一区二区免费不卡| 人人超碰人摸人爱| 国产jlzzjlzz视频免费看| 推油少妇久久99久久99久久| 午夜通通国产精品福利| 亚洲综合精品一区二区三区| 国内揄拍国内精品人妻| 无套内射视频囯产| 高清国产一区二区无遮挡| 国产香蕉一区二区三区在线视频| 丁香五月婷激情综合第九色| 蜜臀av黑人亚洲精品| 人妻丝袜AV中文系列先锋影音| 胶州市| 丰满人妻一区二区三区无码AV| 曰批免费视频播放免费| 日本高清视频网站www| japanese无码中文字幕|