Monthly Archives: May 2009

BasicHttpBinaryBinding for Silverlight

Silverlight 3 beta introduces a binary message encoder on the channel stack.

Binary encoding is implemented as a custom binding, there is no out-of-the-box binary binding.

<bindings>
  <customBinding>
	<binding name="binaryHttpBinding">
	   <binaryMessageEncoding />
         <httpTransport />
      </binding>
  </customBinding>
</bindings>
<endpoint address=""
          binding="customBinding"
          bindingConfiguration="binaryHttpBinding"
          contract="Service" />

If you would set the binding programmatically you have to configure your own CustomBinding instance.

This was the reason to implement the BasicHttpBinaryBinding class as you can find below.

UPDATE May 2010: The method CreateBindingElements copies now the reader quotas and other settings to the binary element.

/// <summary>
// Represents a basic http binding with binary encoding.
/// </summary>
public class BasicHttpBinaryBinding : BasicHttpBinding
{
  /// <summary>
  ///  Initializes a new instance of the BasicHttpBinaryBinding class.
  /// </summary>
  public BasicHttpBinaryBinding()
    : this(BasicHttpSecurityMode.None)
  {
  }

  /// <summary>
  /// Initializes a new instance of the BasicHttpBinaryBinding class.
  /// </summary>
  /// <param name="securityMode">
  /// The value of System.ServiceModel.BasicHttpSecurityMode that specifies 
  /// the type of security that is used with the SOAP message and for the client.
  /// </param>
  public BasicHttpBinaryBinding(BasicHttpSecurityMode securityMode)
    : this(securityMode, true)
  {
  }

  /// <summary>
  /// Initializes a new instance of the BasicHttpBinaryBinding class.
  /// </summary>
  /// <param name="securityMode">
  /// The value of System.ServiceModel.BasicHttpSecurityMode that specifies 
  /// the type of security that is used with the SOAP message and for the client.
  /// </param>
  /// <param name="binaryEncoding">
  /// Indicates whether the binary encoding is enabled or not
  /// </param>
  public BasicHttpBinaryBinding(BasicHttpSecurityMode securityMode, bool binaryEncoding)
    : base(securityMode)
  {
    this.BinaryEncoding = true;
    this.BinaryEncoding = binaryEncoding;
  }

  /// <summary>
  /// Gets or sets a value that indicates whether the binary encoding is enabled or not. 
  /// Default is true.
  /// </summary>
  public bool BinaryEncoding { get; set; }

  /// <summary>
  /// Returns an ordered collection of binding elements contained in the current binding.
  /// </summary>
  public override BindingElementCollection CreateBindingElements()
  {
    BindingElementCollection elements = base.CreateBindingElements();

    if (this.BinaryEncoding)
    {
      // search the existing message encoding element (Text or MTOM) and replace it
      // note: the search must be done with the base type of text and mtom binding element, 
      // because this code is compiled against silverlight also 
      // and there is no mtom encoding available
      for (int i = elements.Count - 1; i >= 0; i--)
      {
        BindingElement element = elements[i];
        if (element.GetType().IsSubclassOf(typeof(MessageEncodingBindingElement)))
        {
          BinaryMessageEncodingBindingElement binaryElement = null;

          if (element is TextMessageEncodingBindingElement)
          {
            // copy settings to binary element
            TextMessageEncodingBindingElement textEncoding = element as TextMessageEncodingBindingElement;
            binaryElement = new BinaryMessageEncodingBindingElement();

            // copy settings
            binaryElement.ReaderQuotas.MaxArrayLength = textEncoding.ReaderQuotas.MaxArrayLength;
            binaryElement.ReaderQuotas.MaxBytesPerRead = textEncoding.ReaderQuotas.MaxBytesPerRead;
            binaryElement.ReaderQuotas.MaxDepth = textEncoding.ReaderQuotas.MaxDepth;
            binaryElement.ReaderQuotas.MaxNameTableCharCount = textEncoding.ReaderQuotas.MaxNameTableCharCount;
            binaryElement.ReaderQuotas.MaxStringContentLength = textEncoding.ReaderQuotas.MaxStringContentLength;
            binaryElement.MaxReadPoolSize = textEncoding.MaxReadPoolSize;
            binaryElement.MaxWritePoolSize = textEncoding.MaxWritePoolSize;

            // binary uses always soap-1.2
            //binaryElement.MessageVersion = textEncoding.MessageVersion;
          }
          else if (element is MtomMessageEncodingBindingElement)
          {
            // copy settings to binary element
            MtomMessageEncodingBindingElement mtomEncoding = element as MtomMessageEncodingBindingElement;
            binaryElement = new BinaryMessageEncodingBindingElement();

            // copy settings
            binaryElement.ReaderQuotas.MaxArrayLength = mtomEncoding.ReaderQuotas.MaxArrayLength;
            binaryElement.ReaderQuotas.MaxBytesPerRead = mtomEncoding.ReaderQuotas.MaxBytesPerRead;
            binaryElement.ReaderQuotas.MaxDepth = mtomEncoding.ReaderQuotas.MaxDepth;
            binaryElement.ReaderQuotas.MaxNameTableCharCount = mtomEncoding.ReaderQuotas.MaxNameTableCharCount;
            binaryElement.ReaderQuotas.MaxStringContentLength = mtomEncoding.ReaderQuotas.MaxStringContentLength;
            binaryElement.MaxReadPoolSize = mtomEncoding.MaxReadPoolSize;
            binaryElement.MaxWritePoolSize = mtomEncoding.MaxWritePoolSize;

            // binary uses always soap-1.2
            //binaryElement.MessageVersion = mtomEncoding.MessageVersion;
          }
          else if (element is BinaryMessageEncodingBindingElement)
          {
            // it's already binary
          }
          else
          {
            string exStr = string.Format("Message encoding type {0} is not implemented.", element.GetType().Name);
            throw new NotImplementedException(exStr);
          }

          if (binaryElement != null)
          {
            elements.RemoveAt(i);
            elements.Insert(i, binaryElement);
            break;
          }
        }
      }
    }

    return elements;
  }

}

The class is Silverlight compilable, therefore you can share it along the Silverlight and wcf-service project.

How to use: instead of the BasicHttpBinding you can use BasicHttpBinaryBinding as following to enable binary encoding.

BasicHttpBinding binding = new BasicHttpBinding();

BasicHttpBinding binding = new BasicHttpBinaryBinding();

Download the code here

Advertisements
Tagged ,