‘class’ must be Xml serializable to be a message part type


As many of you know, BizTalk Server 2004 can represent messages as either XSD schemas or .NET classes.


The most common approach is to use an XSD schema. If you choose to use a .NET class to represent a message, remember that the BizTalk 2004 engine needs to be able to serialize/deserialize your message with the XML serializer.


Consider the following code (which originally appeared in a post on microsoft.public.biztalk.general):

using System;

using Microsoft.XLANGs.BaseTypes;

using System.Xml.Serialization;


namespace FastTrackObjects

{

   [Serializable]

   public class ExcelResults

   {

      public ExcelResults(int requestId, string error)

      {

         RequestId = requestId;

         Error = error;

      }


      [DistinguishedFieldAttribute()]

      public int RequestId;


      [DistinguishedFieldAttribute()]

      public string Error;

   }

}



What is wrong with that code? Well, if you build the orchestration, you will probably receive:


‘FastTrackObjects.ExcelResults’ must be Xml serializable to be a message part type


If you look closely, you notice that the previous class does not have a default constructor. A quick trip to serialization 101 under “XML Serialization Considerations” reveals that “a class must have a default constructor to be serialized by XmlSerializer“.


At deserialization time, the XmlSerializer first creates an instance of the new object and then populates the properties and other fields. This is why a default constructor is required. BizTalk 2004 detects this fact at orchestration compilation time and prevents you from deploying an orchestration that will be unreliable due to lack of serialization.

Comments (4)

  1. Hong Lee says:

    I’ve got the same error….

    As you said…

    I added a default constructor.

    (Here is my class…)

    [Serializable]

    public class POClass {

    [Property(typeof(PropertySchemas.IDs))]

    public string ID;

    public string Item;

    public POClass() { }

    }

    Still…

    a compile error "a class must have a default constructor to be serialized by mlSerializer" reported.

    I think…

    Although there is no default constructor specified in class definition…

    default constructor is provided implicitly when there is no any other constructors.

    so…

    "a class must have a default constructor to be serialized by XmlSerializer"

    means…a class should not be like this…

    public class POClass {

    [Property(typeof(PropertySchemas.IDs))]

    public string ID;

    public string Item;

    public POClass(string s) { ID = s; }

    }

    So…

    I solved the xml-serializable problem

    by adding an attribute that control XML serialization….

    [Serializable]

    public class POClass

    {

    [Property(typeof(PropertySchemas.IDs))]

    [XmlRootAttribute("PO")]

    public string ID;

    public string Item;

    }

    I feel…

    this is not the right way to solve the compile error.

    Plz…

    comment me more…

  2. Gilles says:

    Your first example makes usage of "[Property(typeof(PropertySchemas.IDs))] ".

    If you remove it, you will build.

    As it was explained in another post in newsgroups, you should create a property schema and not define properties in code using PropertyAttribute. Look at http://msdn.microsoft.com/library/en-us/sdk/htm/ebiz_prog_edit_kcpp.asp?frame=true for informations on property schemas.

  3. Hong Lee says:

    I made a property schema and used it in the first example.

    I need "[Property(typeof(PropertySchemas.IDs))]" in a Xml-Serializable class.

    How do I use [Property(typeof(PropertySchemas.IDs))] and

    specify a class as xml-serializable

    (except using an attribute that control XML serialization)?

  4. Gilles says:

    You can always imlpement ISerializable on your class, which will fix the serialization problem.