msgbartop
Around Software Development and Innovation
msgbarbottom

27 Feb 11 Estrarre un XmlDocument da una classe serializzata con DataContractSerializer

Avevo l’esigenza di estrarre da un classe serializzata come XML con un DataContractSerializer di WCF un oggetto di tipo XmlDocument.

Riporto il codice di esempio che potrebbe esser utile a qualcuno.Ecco la classe da serializzare:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;

namespace WcfServices
{
  [DataContract(Name="PROVA",Namespace="http://prova.schemas.it")]
  public class UserMessage
  {
    [DataMember]
    public string MessageType{get;set;}
    [DataMember]
    public string Message { get; set; }
    [DataMember]
    public DateTime Date { get; set; }
  }
}
Ora riporto il codice che serializza in un MemoryStream l'oggetto e
successivamente lo riporta in un XmlDocument:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.IO;
using System.Xml;

namespace WcfServices
{
  public class SerializationHelper
  {
    public static XmlDocument Serialize(UserMessage msg)
    {
      XmlDocument doc = new XmlDocument();
      //use Memory Stream as support object
      MemoryStream mem=new MemoryStream();
      DataContractSerializer dcs = new DataContractSerializer(typeof(UserMessage));
      //write data into memory stream
      dcs.WriteObject(mem, msg);
      //set cursor at begin for reading
      mem.Position = 0;
      doc.Load(mem);
      return doc;
    }
  }
}
Bye
Antonio

27 Feb 11 Un semplice custom WCF Behaviour

Ho scritto ed allego un custom WCF behaviour che collega l’hash del messaggio all’headers e alle properties.

Si tratta di un semplice esempio ma forse serve a qualcun’altro…

:D

Antonio

2010_1_BehaviourSample

27 Feb 11 GZip Encoder WCF XmlDictionaryReaderQuotas MaxStringContentLength 8192 Error

Cercando un MessageEncoder per GZip, ho trovato negli esempi di Microsoft un esempio completo che realizza l’encoder GZIP.

Inserendo lo nel mio progetto dopo un pò di test ho notato il seguente messaggio di errore:

The maximum string content length quota (8192) has been exceeded while reading XML data. This quota may be increased by changing the MaxStringContentLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader.

Il problema è chiaro, bisogna incrementare la proprietà MaxStringContentLength, in realtà la cosa forse più complessa è capire dove farlo. Riporto in seguito la soluzione.

Aprire il file GZipMessageEncodingBindingElement nella classe GZipMessageEncodingBindingElement, cerchiamo il metodo ApplyConfiguration e modificarlo come segue:

//Called by the WCF to apply the configuration settings (the property above) to the binding element
        public override void ApplyConfiguration(BindingElement bindingElement)
        {
            GZipMessageEncodingBindingElement binding = (GZipMessageEncodingBindingElement)bindingElement;
            PropertyInformationCollection propertyInfo = this.ElementInformation.Properties;
            if (propertyInfo["innerMessageEncoding"].ValueOrigin != PropertyValueOrigin.Default)
            {
                switch (this.InnerMessageEncoding)
                {
                    case "textMessageEncoding":
                        TextMessageEncodingBindingElement encoder = new TextMessageEncodingBindingElement();
                        encoder.ReaderQuotas.MaxStringContentLength = int.MaxValue;
                        binding.InnerMessageEncodingBindingElement = encoder;
                        break;
                    case "binaryMessageEncoding":
                        BinaryMessageEncodingBindingElement binEncoder = new BinaryMessageEncodingBindingElement();
                        binEncoder.ReaderQuotas.MaxStringContentLength = int.MaxValue;
                        binding.InnerMessageEncodingBindingElement = binEncoder;
                        break;
                }
            }
            else {
                TextMessageEncodingBindingElement encoder = new TextMessageEncodingBindingElement();
                encoder.ReaderQuotas.MaxStringContentLength = int.MaxValue;
                binding.InnerMessageEncodingBindingElement = encoder;
            }
        }

Questo funziona sia per i messaggi con Message Encoding di base di tipo text che binary.

Bye

Antonio