Adding custom behavior to WCF service configuration file

Adding custom behavior to WCF service configuration file

Hi,

 

Few days back I was trying to add custom behaviour to my WCF service and found out that many users have issues in adding these behaviour to the congig file so I thought of sharing the code to implment IEndpointBehavior and IServiceBehavior and adding these behaviors to the WCF service configuration file.

In the code below I have implemented Validate method to throw an exception at runtime when the contract is two way. So we will get an exception at the runtime during host.Open().

 

I have also shared the App.config file where these behaviors are added to EndpointBehaviours and ServiceBehaviours sections.

  

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.ServiceModel.Description;

using System.ServiceModel.Dispatcher;

using System.ServiceModel.Configuration;

using System.ServiceModel;


namespace
MyNamespace
{
  class Program
  {
    static void Main(string[] args)
    { 
      ServiceHost serviceHost = new ServiceHost(typeof(ServiceContracts));
      serviceHost.Open();
      Console.WriteLine("Service is running..");
      Console.Read();
    }
 
}

  public class ServiceContracts : IServiceContract

  {

    public void Method1()

    {

        return;

    }

  }


  public
class EndpointBehaviorMessageInspector : BehaviorExtensionElement, IDispatchMessageInspector, IClientMessageInspector, IEndpointBehavior

  {

    public object AfterReceiveRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel, InstanceContext instanceContext)

    {

      Console.WriteLine("AfterReceiveRequest called.");

      return null;

    }

    public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)

    {

      Console.WriteLine("BeforeSendReply called.");

    }


    public
override Type BehaviorType

    {

      get { return typeof(EndpointBehaviorMessageInspector); }

    }


    protected
override object CreateBehavior()
   
{
      
return new EndpointBehaviorMessageInspector();
    }

    public void AfterReceiveReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
    {
     
return;
    }

    public object BeforeSendRequest(ref System.ServiceModel.Channels.Message request, IClientChannel channel)
    {
      return "";
    }

    // IEndpointBehavior Members
    public void AddBindingParameters(ServiceEndpoint serviceEndpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {
      return;
    }

    public void ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime behavior)
    {
      behavior.MessageInspectors.Add(new EndpointBehaviorMessageInspector());
    }

    public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher)
    {
      endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new EndpointBehaviorMessageInspector());
    }

    public void Validate(ServiceEndpoint serviceEndpoint)
    {
      if (serviceEndpoint.Contract.Operations[0].IsOneWay.Equals(false))
      {
        throw new ArgumentException("One way is not allowed");
      }
    }
  }

  public class EnforceGreetingFaultBehavior : BehaviorExtensionElement, IServiceBehavior, IEndpointBehavior
  {
    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {
      return;
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
      return;
    }

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
      foreach (ServiceEndpoint se in serviceDescription.Endpoints)
      {
        if (se.Contract.Operations[0].IsOneWay.Equals(false))
        {
          throw new ArgumentException("Sorry, contract needs to be two way");
        }
      }
    }

    public override Type BehaviorType
    {
      get { return typeof(EnforceGreetingFaultBehavior); }
    }

    protected
override object CreateBehavior()
    {
      return new EnforceGreetingFaultBehavior();
    }

    public void AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
    {
      return;
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
      return;
    }

    public
void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
      return;
    }

    public void Validate(ServiceEndpoint endpoint)
    {
      throw new NotImplementedException();
    }
  }

  [
ServiceContract]
  public interface IServiceContract
  {
    [OperationContract(IsOneWay = false)]
    void Method1();
    }
}

Application configuration file to add behaviour is below.

<?xml version="1.0"?>
<configuration>
                <system.serviceModel>
                                <bindings>
                                                <basicHttpBinding>
                                                                <binding name="basicHttpConfig">
                                                                </binding>
                                                </basicHttpBinding>                                    
                                </bindings>
                                <services>
                                                <service name="MyNamespace.ServiceContracts" behaviorConfiguration="metadataSupport">
                                                                <host>
                                                                                <baseAddresses>
                                                                                                <add baseAddress="http://localhost:50002/MyAddressOn"/>
                                                                                </baseAddresses>
                                                                </host>
                                                                <endpoint contract="MyNamespace.IServiceContract" bindingName="basicHttpConfig" binding="basicHttpBinding"
                                                                                                  bindingConfiguration="basicHttpConfig" address="http://localhost:50002/MyAddressOn"

                                                                                                  
behaviorConfiguration="MyEndpointBehavior">

                                                                </endpoint>

                                                                <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

                                                </service>

                                </services>

                                <behaviors>

                                                <serviceBehaviors>

                                                                <behavior name="metadataSupport">

                                                                                <serviceMetadata httpGetEnabled="true" httpGetUrl="http://localhost:50002/MyAddressOn"/>

                                                                                <!–Add the new custom service behaviour to service behavior–>

                                                                                <MyServiceBehavior/>

                                                                </behavior>

                                                </serviceBehaviors>

                                                <endpointBehaviors>

                                                                <behavior name="MyEndpointBehavior">

                                                                                <!–add the custom endpointbehavior to endpoint behavior–>

                                                                                <MyEndpointBehavior/>

                                                                </behavior>

                                                </endpointBehaviors>

                                </behaviors>

                                <extensions>

                                                <behaviorExtensions>

                                                                <!–Type here is typeof(EndpointBehaviorMessageInspector).AssemblyQualifiedName–>

                                                                <add name="MyEndpointBehavior" type="MyNamespace.EndpointBehaviorMessageInspector, Blog1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>

                                                                <add name="MyServiceBehavior" type="MyNamespace.EnforceGreetingFaultBehavior, Blog1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"/>                                                       

                                                </behaviorExtensions>

                                </extensions>                 

                </system.serviceModel>

                <startup>

                                <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>

                </startup>

</configuration>


Thanks,

Neha  

About the Author