views:

16

answers:

1

I've created a custom behaviour for use with a WCF service to log all errors to the application log. I have made a BehaviorExtensionElement for the behaviour:

public ErrorLoggingBehaviorExtensionElement : BehaviorExtensionElement
{
    public ErrorLoggingBehaviorExtensionElement() { }

    /* - Elements removed for brevity - */
}

I am attempting to apply this in my configuration as follows:

<extensions>
  <behaviorExtensions>
    <add name="errorLogging"
         type="ErrorLoggingBehaviorExtensionElement, Logging, Version=1.0.0.0, 
               Culture=neutral, PublicKeyToken=56e8273d901d717f"/>
  </behaviorExtensions>
</extensions>

<services>
  <service name="TestService" behaviorConfiguration="TestServiceBehavior">
    <endpoint address="" 
              binding="wsHttpBinding" 
              contract="Test_Service.ITestService"/>
    <endpoint address="mex" 
              binding="mexHttpBinding" 
              contract="IMetadataExchange"/>
  </service>
</services>

<behaviors>
  <serviceBehaviors>
    <behavior name="TestServiceBehavior">
      <serviceMetadata httpGetEnabled="true"/>
      <errorLogging />
    </behavior>
  </serviceBehaviors>
</behaviors>

NOTE: The "type" attribute on the behavior registration element is actually on a single line in my configuration file to overcome this known issue. Line-breaks have been added for your eyes.

This generates the following application error when trying to view the service page:

An error occurred creating the configuration section handler for system.serviceModel/behaviors: No parameterless constructor defined for this object.

Removing the <errorLogging /> element makes the error disappear, but I can't see how it is related to the error being reported.

A: 

The problem is actually deep within the configuration element's child elements.

One of the configuration properties was an enumeration, decorated with a TypeConverterAttribute to perform the conversion from string to enumeration:

[ConfigurationProperty("level", IsRequired=false)]
[TypeConverter(typeof(EnumConverter))]
public LogLevel Level
{
    get { ... }
    set { ... }
}

The exception being thrown actually refers to the type EnumConverter not having a parameterless constructor (in fact it requires the type of the enumeration to convert to and from).

To resolve this, I switched to creating the ConfigurationProperty in the element's constructor instead of using the declarative model. At some point, I will probably create an EnumConverter<T> class so that it can be used declaratively.

This caused me about a day of digging to finally resolve.

Programming Hero