Share via


Message Header vs. Context Terminology

Is anyone confused about the conflicting terminlogy I have seen in the BizTalk documentation regarding BizTalk message headers and contexts? I have always understood a message to be just a context and a body. There is no 'header' in a BizTalk message that has been received by an adapter. For instance, here is an exerpt from the product documenation and I have seen this terminlogy conflict in other whitepapers and documentation.

A message is made up of a header section and a body section:

· Headers are simple name-value pairs. The names are all drawn from various property schemas. The system provides some core schemas and BizTalk Server applications can add their own.

I believe this should read:

A message is made up of a context and a body:

· The context is composed of simple name-value pairs. The names are all drawn from various property schemas. The system provides some core schemas and BizTalk Server applications can add their own.

Comments

  • Anonymous
    January 02, 2006
    The comment has been removed
  • Anonymous
    January 03, 2006
    The comment has been removed
  • Anonymous
    January 03, 2006
    You might also want to point out that there are size limitations to the data that can be embedded in these properties ;-)
  • Anonymous
    January 03, 2006
    thx Todd. So are you saying there is not sufficient documentation regarding size limitations of properties in a message context?
  • Anonymous
    January 10, 2006
    Here is the code to enumerat through the context properties that Mick Badran asked for above.





    #region References

    using System;

    using System.Xml;

    using System.Xml.Schema;

    using System.IO;

    using System.Text;

    using System.Reflection;

    using System.Collections;

    using System.Diagnostics;

    using Microsoft.XLANGs.BaseTypes;

    using Microsoft.XLANGs.Core;

    using BTS;

    using BTF2;



    using ENI.SI231.Common;

    #endregion



    namespace ENI.SI231.IntegrationEngine

    {

    [Serializable]

    public class MessageUtility

    {

    #region Constants

    private const string CONTEXT_PROPERTIES = "Context Properties";

    private const string CONTENT_PROPERTIES = "Content Properties";

    private const string PART_PROPERTIES = "Part Properties";

    private const string PART_SCHEMA = "Part Schema";

    private const string PART_STREAM = "Part Stream";

    private const string LINE = "---------------------------------------------------------------";

    private const string NONE = "None";

    private const string PROPERTY_FORMAT = "{0}: {1}";

    private const string PART_FORMAT = "Part Name: {0}";

    private const string SOURCE = "BizTalk Utilities";

    private const string ERROR_MESSAGE_FORMAT = "Class: {0} Method: {1} : Message: {2}";

    #endregion



    #region Fields

    private XLANGMessage message;

    // private XmlDocument xmlDoc;

    #endregion



    #region Constructors

    public MessageUtility()

    {




    }



    public MessageUtility(XLANGMessage message)

    {

    this.message = message;

    }



    #endregion



    #region Properties

    public XLANGMessage Message

    {

    get

    {

    return message;

    }

    set

    {

    message = value;

    }

    }



    public XmlDocument XmlMessage

    {

    get

    {

    return (XmlDocument)message[0].RetrieveAs(typeof(XmlDocument));

    }

    }



    #endregion



    #region Public Methods



    /// <summary>

    ///

    /// </summary>

    public void TraceProperties()

    {

    try

    {

    if (message != null)

    {

    bool ok;

    object value;

    Type[] types;

    Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();

    if (assemblies != null && assemblies.Length > 0)

    {

    // Context Properties

    Trace.WriteLine(LINE);

    Trace.WriteLine(CONTEXT_PROPERTIES);

    Trace.WriteLine(LINE);

    ok = false;

    for (int j = 0; j < assemblies.Length; j++)

    {

    if (assemblies[j] != null)

    {

    types = assemblies[j].GetTypes();

    if (types != null)

    {

    for (int i = 0; i < types.Length; i++)

    {

    if (types[i].BaseType == typeof(MessageContextPropertyBase))

    {

    value = message.GetPropertyValue(types[i]);

    if (value != null)

    {

    Trace.WriteLine(string.Format(PROPERTY_FORMAT, types[i].FullName, value));

    ok = true;

    }

    }

    }

    }

    }

    }

    if (!ok)

    Trace.WriteLine(NONE);



    // Content Properties

    Trace.WriteLine(LINE);

    Trace.WriteLine(CONTENT_PROPERTIES);

    Trace.WriteLine(LINE);

    ok = false;

    for (int j = 0; j < assemblies.Length; j++)

    {

    if (assemblies[j] != null)

    {

    types = assemblies[j].GetTypes();

    if (types != null)

    {

    for (int i = 0; i < types.Length; i++)

    {

    if (types[i].BaseType == typeof(MessageDataPropertyBase))

    {

    value = message.GetPropertyValue(types[i]);

    if (value != null)

    {

    Trace.WriteLine(string.Format(PROPERTY_FORMAT, types[i].FullName, value));

    ok = true;

    }

    }

    }

    }

    }

    }

    if (!ok)

    Trace.WriteLine(NONE);

    }

    }

    }

    catch (Exception ex)

    {

    EventLog.WriteEntry(SOURCE,

    string.Format(ERROR_MESSAGE_FORMAT,

    MethodInfo.GetCurrentMethod().ReflectedType.ToString(),

    MethodInfo.GetCurrentMethod().ToString(),

    ex.Message),

    EventLogEntryType.Error);

    }

    }



    public void TraceParts()

    {

    try

    {

    if (message != null &&

    message.Count > 0)

    {

    IEnumerator e = message.GetEnumerator();

    XLANGPart part;

    XmlSchema xmlSchema;

    XmlDocument xmlDocument;

    Type type = typeof(Microsoft.XLANGs.BaseTypes.Size);

    Assembly assembly = type.Assembly;

    Type[] types = assembly.GetTypes();

    StringWriter writer;

    object value;

    bool ok;

    while (e.MoveNext())

    {

    part = (XLANGPart)e.Current;

    if (part != null)

    {

    Trace.WriteLine(string.Format(PART_FORMAT, part.Name));

    Trace.WriteLine(LINE);

    if (types != null)

    {

    Trace.WriteLine(PART_PROPERTIES);

    Trace.WriteLine(LINE);

    ok = false;

    for (int i = 0; i < types.Length; i++)

    {

    if (types[i].BaseType == typeof(PartContextPropertyBase))

    {

    value = message.GetPropertyValue(types[i]);

    if (value != null)

    {

    ok = true;

    Trace.WriteLine(string.Format(PROPERTY_FORMAT, types[i].Name, value));

    }

    }

    }

    if (!ok)

    Trace.WriteLine(NONE);

    }

    Trace.WriteLine(LINE);

    Trace.WriteLine(PART_SCHEMA);

    Trace.WriteLine(LINE);

    xmlSchema = part.XmlSchema;

    writer = new StringWriter();

    xmlSchema.Write(writer);

    Trace.Write(writer.ToString());

    Trace.WriteLine(LINE);

    Trace.WriteLine(PART_STREAM);

    Trace.WriteLine(LINE);

    xmlDocument = (XmlDocument)part.RetrieveAs(typeof(XmlDocument));

    Trace.Write(xmlDocument.OuterXml);

    Trace.WriteLine(LINE);

    }

    }

    }

    }

    catch (Exception ex)

    {

    EventLog.WriteEntry(SOURCE,

    string.Format(ERROR_MESSAGE_FORMAT,

    MethodInfo.GetCurrentMethod().ReflectedType.ToString(),

    MethodInfo.GetCurrentMethod().ToString(),

    ex.Message),

    EventLogEntryType.Error);

    }

    }



    public void TraceAll()

    {

    TraceProperties();

    TraceParts();

    }



    public string GetPartSimpleValue(XLANGPart part)

    {

    XmlDocument document;

    document = (XmlDocument)part.RetrieveAs(typeof(XmlDocument));

    return document.DocumentElement.InnerText;

    }

    #endregion

    }

    }

  • Anonymous
    March 17, 2006
    Request for more documentation:

    1) In developing an Adapter I want to define some global context properties, i.e. "MyAdapter.NativeAddress". I have deployed the property schema (can see it in HAT, port filters, etc), but I can't use it in my Orchestration expression -- there's no documentation on this one. Why can't I assign a value to my custom property just like I can with, say, "BTS.MessageID"? Thanks in advance.

    2) I want to add my adapter to the list that can be bound within an orchestration ("specify now"). Is this an undocumented registration option -- how do I do this?
  • Anonymous
    March 21, 2006
    Hi Jen
    Hope this answers your questions...

    1) - You need to derive your properties in their property schema from MessageContextPropertyBase - this is the Propery Schema Base property on each property schema item.  This lets the orchestration designer know that the property is just a context property - not necessarily expected to be found in the message itself via promotion.

    2) I don't believe this list is extensible - plus they shouldn't really want people to use this "early binding" anyway - it is really only useful for quick and dirty demos.