EagleMl Web Service - Custom Classes and Overrides

This section describes some additional actions you should fulfill to make your work more effective.

Create a CustomTextMessageBindingElement class.

internal class CustomTextMessageBindingElement : MessageEncodingBindingElement, IWsdlExportExtension     {         #region Fields         private MessageVersion _msgVersion;         private string _mediaType;         private string _encoding;         private readonly XmlDictionaryReaderQuotas _readerQuotas;         #endregion         #region Properties         public override MessageVersion MessageVersion         {             get { return _msgVersion; }             set             {                 if (value == null)                     throw new ArgumentNullException("value");                 _msgVersion = value;             }         }         public string MediaType         {             get { return _mediaType; }             set             {                 if (value == null)                     throw new ArgumentNullException("value");                 _mediaType = value;             }         }         public string Encoding         {             get { return _encoding; }             set             {                 if (value == null)                     throw new ArgumentNullException("value");                 _encoding = value;             }         }         // This encoder does not enforces any quotas for the unsecure messages. The         // quotas are enforced for the secure portions of messages when this encoder         // is used in a binding that is configured with security.         public XmlDictionaryReaderQuotas ReaderQuotas         {             get { return _readerQuotas; }         }         #endregion         #region Constructors         private CustomTextMessageBindingElement(CustomTextMessageBindingElement binding)             : this(binding.Encoding, binding.MediaType, binding.MessageVersion)         {             _readerQuotas = new XmlDictionaryReaderQuotas();             binding.ReaderQuotas.CopyTo(_readerQuotas);         }         public CustomTextMessageBindingElement(string encoding, string mediaType,                                                 MessageVersion msgVersion)         {             if (encoding == null)                 throw new ArgumentNullException("encoding");             if (mediaType == null)                 throw new ArgumentNullException("mediaType");             if (msgVersion == null)                 throw new ArgumentNullException("msgVersion");             _msgVersion = msgVersion;             _mediaType = mediaType;             _encoding = encoding;             _readerQuotas = new XmlDictionaryReaderQuotas();         }         public CustomTextMessageBindingElement(string encoding, string mediaType)             : this(encoding, mediaType, MessageVersion.Soap11WSAddressing10)         {                     }         public CustomTextMessageBindingElement(string encoding)             : this(encoding, "text/xml")         {                     }         public CustomTextMessageBindingElement()             : this("UTF-8")         {         }         #endregion         #region Overrides         public override BindingElement Clone()         {             return new CustomTextMessageBindingElement(this);         }         public override IChannelFactory<TChannel> BuildChannelFactory<TChannel>(BindingContext context)         {             if (context == null)                 throw new ArgumentNullException("context");             context.BindingParameters.Add(this);             return context.BuildInnerChannelFactory<TChannel>();         }         public override bool CanBuildChannelFactory<TChannel>(BindingContext context)         {             if (context == null)                 throw new ArgumentNullException("context");             return context.CanBuildInnerChannelFactory<TChannel>();         }         public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)         {             if (context == null)                 throw new ArgumentNullException("context");             context.BindingParameters.Add(this);             return context.BuildInnerChannelListener<TChannel>();         }         public override bool CanBuildChannelListener<TChannel>(BindingContext context)         {             if (context == null)                 throw new ArgumentNullException("context");             context.BindingParameters.Add(this);             return context.CanBuildInnerChannelListener<TChannel>();         }         public override T GetProperty<T>(BindingContext context)         {             if (typeof(T) == typeof(XmlDictionaryReaderQuotas))                 return (T)(object)_readerQuotas;             return base.GetProperty<T>(context);         }         #endregion         #region IMessageEncodingBindingElement Members         public override MessageEncoderFactory CreateMessageEncoderFactory()         {             return new CustomTextMessageEncoderFactory(MediaType, Encoding, MessageVersion);         }         #endregion         #region IWsdlExportExtension Members         void IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext context)         { }         void IWsdlExportExtension.ExportEndpoint(WsdlExporter exporter, WsdlEndpointConversionContext context)         {             // The MessageEncodingBindingElement is responsible for ensuring that the WSDL has the correct             // SOAP version. We can delegate to the WCF implementation of TextMessageEncodingBindingElement for this.             var mebe = new TextMessageEncodingBindingElement { MessageVersion = _msgVersion };             ((IWsdlExportExtension)mebe).ExportEndpoint(exporter, context);         }         #endregion     }

The most important methods are:

public CustomTextMessageBindingElement(string encoding) and public CustomTextMessageBindingElement()

In these methods, set the default contentType and encoding (text/xml and UTF-8).

Create CustomTextMessageEncoderFactory and CustomTextMessageEncoder classes.

public class CustomTextMessageEncoderFactory : MessageEncoderFactory     {         private MessageEncoder encoder;         private MessageVersion version;         private string mediaType;         private string charSet;         internal CustomTextMessageEncoderFactory(string mediaType, string charSet,             MessageVersion version)         {             this.version = version;             this.mediaType = mediaType;             this.charSet = charSet;             this.encoder = new CustomTextMessageEncoder(this);         }         public override MessageEncoder Encoder         {             get             {                 return this.encoder;             }         }         public override MessageVersion MessageVersion         {             get             {                 return this.version;             }         }         internal string MediaType         {             get             {                 return this.mediaType;             }         }         internal string CharSet         {             get             {                 return this.charSet;             }         }     }

CustomTextMessageEncoderFactory is a support class. The CustomTextMessageEncoder class is as follows:

public class CustomTextMessageEncoder : MessageEncoder     {               private CustomTextMessageEncoderFactory factory;         private XmlWriterSettings writerSettings;         private string contentType;         public CustomTextMessageEncoder(CustomTextMessageEncoderFactory factory)         {             this.factory = factory;             this.writerSettings = new XmlWriterSettings();             this.writerSettings.Encoding = Encoding.GetEncoding(factory.CharSet);             this.contentType = string.Format("{0}; charset={1}",                 this.factory.MediaType, this.writerSettings.Encoding.HeaderName);         }         public override string ContentType         {             get             {                 return this.contentType;             }         }         public override string MediaType         {             get             {                 return factory.MediaType;             }         }         public override MessageVersion MessageVersion         {             get             {                 return this.factory.MessageVersion;             }         }         public override System.ServiceModel.Channels.Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)         {             byte[] msgContents = new byte[buffer.Count];             Array.Copy(buffer.Array, buffer.Offset, msgContents, 0, msgContents.Length);             bufferManager.ReturnBuffer(buffer.Array);             MemoryStream stream = new MemoryStream(msgContents);             return ReadMessage(stream, int.MaxValue);         }         public override System.ServiceModel.Channels.Message ReadMessage(Stream stream, int maxSizeOfHeaders, string contentType)         {             try             {                 XmlReader reader = XmlReader.Create(stream);                 return System.ServiceModel.Channels.Message.CreateMessage(reader, maxSizeOfHeaders, this.MessageVersion);             }             catch (Exception e)             {                 stream.Position = 0;                 string value="";                 using (var strreader = new StreamReader(stream, Encoding.UTF8))                 {                     value = strreader.ReadToEnd();                 }                 if (value.Contains("<ERROR>"))                 {                     int k = value.IndexOf("<ERROR>");                     value=value.Substring(k + 7);                     k = value.LastIndexOf("</ERROR>");                     if (k > 0)                     {                         value = value.Substring(0,k);                     }                 }                                 System.ServiceModel.FaultCode fc = new System.ServiceModel.FaultCode("Receiver");                 System.ServiceModel.Channels.Message m = Message.CreateMessage(this.MessageVersion, fc, value, "fault");                 return m;             }         }         public override ArraySegment<byte> WriteMessage(System.ServiceModel.Channels.Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset)         {             MemoryStream stream = new MemoryStream();                        XmlWriter writer = XmlWriter.Create(stream, this.writerSettings);             message.WriteMessage(writer);             writer.Close();             byte[] messageBytes = stream.GetBuffer();             int messageLength = (int)stream.Position;             stream.Close();             int totalLength = messageLength + messageOffset;             byte[] totalBytes = bufferManager.TakeBuffer(totalLength);             Array.Copy(messageBytes, 0, totalBytes, messageOffset, messageLength);             ArraySegment<byte> byteArray = new ArraySegment<byte>(totalBytes, messageOffset, messageLength);             return byteArray;         }                       public override void WriteMessage(System.ServiceModel.Channels.Message message, Stream stream)         {             XmlWriter writer = XmlWriter.Create(stream, this.writerSettings);             message.WriteMessage(writer);             writer.Close();         }         public override bool IsContentTypeSupported(string contentType)         {             if (contentType == "text/plain" || contentType== "text/xml")                 return true;             return base.IsContentTypeSupported(contentType);         }            }

The CustomTextMessageEncoder class requires the following fixes:

  • The content type fix should be made in the IsContentTypeSupported(string contentType) method. Fix possible incorrect contentTypes from EagleMlWebService.

  • Non-soap messages processing fix. The fix should be made in the ReadMessage(Stream stream, int maxSizeOfHeaders, string contentType) method.

Add the GenerateUID() method which generates a unique correlationID.

// unique id generation         private static string GenerateUID()         {             long i = 1;             foreach (byte b in Guid.NewGuid().ToByteArray())             {                 i *= ((int)b + 1);             }             return string.Format("{0:x}", i - DateTime.Now.Ticks).ToUpper();         }

Â