WCF Behavior

Posted: January 4, 2009 in Uncategorized, WCF
Tags: ,

I ended my last post on WCF Dispatcher extension points with the note that we need WCF behavior to attach the components extending WCF functionality to the runtime.In this post I will describe the various WCF behaviors and how they can be plugged into the WCF runtime.

There are 4 types of behaviors in WCF : Service ,Endpoint,Operation and Contract ,each with a different scope of effect.To create each of this behavior we need to implement a separate interface having the same methods with similar intentions but with different parameters.The purpose of these methods is described below:

  1. AddBindingParameters – This method is used to pass custom information to the binding.
  2. Validate – This method is used to validate the service description.
  3. ApplyDispatchBehavior/ApplyClientBehavior – This method is used to add the extension components to DispatchRuntime/ClientRuntime e.g. MessageInspector,ParameterInspectors etc.

The WCF behaviors can be added to the runtime using the following ways:

  • Programmatically – This I will discuss in details with the individual types of behavior
  • Attributes – In this case the behavior class needs to implement the corresponding behavior interface and extend the attribute class.Then that attribute needs to be applied to the service class implementing the ServiceContract as shown below:

         public class ServicePoolBehavior : Attribute,IServiceBehavior
         {
             …..
         }

          [ServiceContract]

          public interface ITest
          {
             …..
          }
         [ServicePoolBehavior(MaxPoolSize=10,MinPoolSize=2,IncrementSize=2)]

         public class Test:ITest
         {
            ……
         }

  • Configuration – Here we need to implement a custom behavior extension element by extending the System.ServiceModel.BehaviorExtensionElement class and then add the new behavior in the config as shown below:

         public class ServicePoolBehaviorExtensionElement:BehaviorExtensionElement
        {
          ………..

          …………..

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

           protected override object CreateBehavior()
           {
              ServicePoolBehavior behavior = new ServicePoolBehavior();
              behavior.MaxPoolSize = Convert.ToInt32( this.ElementInformation.Properties[“maxPoolSize”].Value);
              behavior.MinPoolSize = Convert.ToInt32( this.ElementInformation.Properties[“minPoolSize”].Value);
              behavior.IncrementSize =Convert.ToInt32( this.ElementInformation.Properties[“incrementSize”].Value);
              return behavior;
          }
      }

      <extensions>
            <behaviorExtensions>
                <add name=”poolBehavior” type=”SB.ServiceModel.Pool.ServicePoolBehaviorExtensionElement, SB.ServiceModel.Pool, Version=1.0.0.0,  Culture=neutral, PublicKeyToken=null” />
            </behaviorExtensions>
        </extensions>
        <behaviors>
            <serviceBehaviors>
                <behavior name=”testBehavior”>
                    <serviceDebug includeExceptionDetailInFaults=”true” />
                    <serviceMetadata httpGetEnabled=”true” httpGetUrl=”
http://localhost:9001/Meta” />
                    <poolBehavior minPoolSize=”2″ maxPoolSize=”10″ incrementSize=”2″/>
                </behavior>
            </serviceBehaviors>
        </behaviors>

Now we will discuss about the individual types of behaviors:

  • ServiceBehavior
    • Need to implement the System.ServiceModel.Description.IServiceBehavior interface.
    • This behavior applies for the entire service runtime including the ServiceHostBase.
    • This behavior can be added by attribute,configuration or code.The following snippet shows how we can add a service behavior programmatically:

                    using (ServiceHost host = new ServiceHost(typeof(SampleService.Test)))
                    {

                       SB.ServiceModel.Pool.ServicePoolBehavior behavior = new SB.ServiceModel.Pool.ServicePoolBehavior();
                       behavior.IncrementSize = 2;
                       behavior.MaxPoolSize = 10;
                       behavior.MinPoolSize = 2;
                       host.Description.Behaviors.Add(behavior);

                       …….

                  }

  • EndpointBehavior
    • Need to implement the System.ServiceModel.Description.IEndpointBehavior interface.
    • This behavior customizes the runtime of a particular endpoint and associated EndpointDispatcher object.
    • This behavior can be added by configuration or code.The following snippet shows how we can add a endpoint behavior programmatically:

                    foreach (ServiceEndpoint se in host.Description.Endpoints) se.Behaviors.Add(new CustomBehavior());

  • ContractBehavior
    • Need to implement the System.ServiceModel.Description.IContractBehavior interface.
    • This behavior customizes the runtime of a particular contract and associated DispatchRuntime/ClientRuntime object.
    • This behavior can be added by attribute or code.The following snippet shows how we can add a contract behavior programmatically:

                   foreach (ServiceEndpoint se in host.Description.Endpoints)
                   {
                        se.Contract.Behaviors.Add(new CustomBehavior);
                    }

  • OperationBehavior
    • Need to implement the System.ServiceModel.Description.IOperationBehavior interface.
    • This behavior customizes the runtime of a particular operation and associated DispatchOperation/ClientOperation object.
    • This behavior can be added by attribute or code.The following snippet shows how we can add a operation behavior programmatically:

                    foreach (ServiceEndpoint se in host.Description.Endpoints)
                    {
                          foreach (OperationDescription od in se.Contract.Operations)
                          {
                                  od.Behaviors.Add(new CustomBehavior);
                          }
                   }

With this much understanding what all different behaviors are available and how to hook them to the runtime we are ready to explore the individual extension points in details from next post onwards.

Advertisements
Comments
  1. Santthosh says:

    Great article, but I still don’t understand how the attributes (minPoolSize, maxPoolSize, incrementSize) are read by the system.ServiceModel configuration

    Can you please post the complete code for ServicePoolBehaviorExtensionElement and SevicePoolBehavior. When I tried I get a sever error

    Parser Error Message: Unrecognized attribute ‘XXX’. Note that attribute names are case-sensitive.

  2. sankarsan says:

    @Santosh:The code used for initializing the properties was wrong.
    I have corrected that.
    Thanks a lot for pointing out.

  3. Kiran says:

    Hi,
    Thank you for posting the article. I have built my services with the message inspectors for validation purposes, which gets registered from the behavior element on the service endpoint.
    For some reason, i am not able to get this working. the endpoint on the service has a behaviorConfiguration set to the custom behavioe element extension. i want to read the attributes on the behavior element. I followed the same way you have explained, with the only difference that your behavior configuration is set on the service but i did on the one of the endpoints of the service. Can you shed some light on this issue?

    Thanks
    Kiran

  4. sankarsan says:

    Kiran – I have created another sample.Please refer to it.
    http://dl.dropbox.com/u/9377325/WCFBehaviorDemo.zip

    Also let me know the exact issue u are facing.

    • Kiran says:

      Sankarsan, Thank you for your quick response. I will take a look into the demo code. I did some tweaks as per msdn and some other blogs online and solved the issue. My actual issue was that, i have a behavior extension configured on a service endpoint. example below:

      From my configuration file above, i want to access the values of attribute1 and attribute2 from my behavior element extensions class which extends from the “behaviorExtensionElement” abstract class so that i can use these values at some point in the message inspectors where i do the service validation.
      I have tried exactly the same way you described in this post above, but was not able to access. Then i tried by adding another configuration property as below:

      [ConfigurationProperty(“attribute1”)]
      public string Attribue1
      {
      get{return this[“attribute1”] as string}
      }
      This way i am able to access the values as expected. The configuration property allows to read the elements from the configuration file using reflection.

      Any ways, sorry for my bad compilation of text, as i have to do all this in a plain text file.

      Also i have one more question. I would like to pass some authorization info to the service as part of the MessageHeaders to a WCF service. On the service side i am interpreting the incomming request to read the headers from, looking by the name of the header and the namespace. I am able to read the headers if i use either of the basic or ws http bindings. But my services are all exposed via REST using webHttpBinding. When i try to add headers it gives me an error “Envelope ‘envelopeNone’ does not support adding message headers”, which is reasonable as my service does not have any SOAP envelope, but when i try to add the headers as a name value pair to the request, but on the service side i could not read them either by using the incomming request object nor by the weboperationcontext(weboperationcontext is NULL in the service). Can you please help me to resolve this.

      Thanks in advance
      Kiran Pedda

  5. Liz says:

    Hi Sankarsan,

    After adding a service extension behavior, i am getting communication exception : the server did not provide a meaningful reply; this might caused by contract mismatch, a premature session shutdown or an internal server error.

    Below is the config:

    if i commented from servicebehaviors, the error disappear, this caused me not able to add extension behavior. Kindly help

  6. Vivek Shivalkar says:

    Hi Sankarsan,
    Thanks for your post. Can you please tell me that if I want to call a method of a web service which takes some parameters, how can I do that using WCF Behavior which i have added in web.config.

    Regards,
    Vivek Shivalkar.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s