Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
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.