12

正しいweb.configを使用してIErrorHandlerをプロジェクトに統合できません

.net 4のwebclientsによって消費されている正常に動作しているWCFがありますが、すべてのサービスメソッドのキャッチオールとしてIErrorhandlerをグローバルエラーロガーとして設定しようとすると、物事が急速に失敗します-主にweb.config部分に関係します!助けてください。

3つのサービスは、IReport、IServiceCustomer、IServiceUserです。

次のようなMyErrorClass.csという別のクラスにIErrorHandlerを実装しました。

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はどのようになりますか。これは、IErrorHandlerを使用していない場合に、web.configの元の作業抽出物がどのように表示されるかを示しています。

  <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>

誰かがこのWCFnoobに修正されたweb.configを送ってください。私は削除して再試行し続け、どこにも行きません(これで何日も失ってしまいました):(

4

2 に答える 2

15
<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バグ)。

于 2012-09-14T14:43:02.583 に答える
8

少し遅れていますが、他のユーザーにとっては(私の意見では)より良いアプローチであり、上記のコードを少し変更するだけで済みます

あなたになら変えられる:

    public class WcfErrorServiceBehaviour : IServiceBehavior

に:

    public class WcfErrorServiceBehaviourAttribute : Attribute, IServiceBehavior

これで、次のようにサービスクラスの属性としてこれを使用できます。

    [WcfErrorServiceBehaviour]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,
                     ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class MXServiceCommands : IMXServiceCommands
    {
    }

これが他の人の助けになることを願っています。

于 2015-05-22T08:16:43.970 に答える