It took me a while, but v1.0 of the BizTalk Software Factory is finally on CodePlex.
You can get it from http://www.codeplex.com/bsf
This first release took CodePlex/BASF developed by Dijkstra as a basis and added some functionality.
- Create BizTalk multi project solution structures using a wizard
- Create BizTalk single project solution, grouping artifacts into folders, using a wizard
- Guidance for adding Schemas to a project
- Guidance for adding Maps to a project
- Guidance for adding Orchestrations to a project
- Guidance for adding pipelines to a project
Future releases will contain also Unit Test and setup projects.
On the project I'm working on at the moment we're using custom exceptions in BizTalk. We have adopted the exception handling part of the ESB guidance and so the custom exception consists of a string indicating what to do next and an XLANGMessage object to store messages in.
There was something not working as expected so I had to debug it. I wasn't very familiar with custom exceptions in BizTalk so I searched the internet for some information. On this blog by Tomas Restrepo I found some interesting tips and information:
Tip #1: Exceptions are not serializable by default. If you create a custom exception class, it is your responsibility to ensure it is serializable.
Tip #2: Marking an exception class with [Serializable] is not enough. System.Exception implements ISerializable, so it forces you to do so as well.
Here's what you should keep in mind when writing an exception class:
- Mark the exception type with the [Serializable] attribute.
- Add an empty protected serialization constructor that simply delegates to the base class: protected MyException(SerializationInfo info, StreamingContext ctxt) : base(info, ctxt)
For most exception classes, this will be enough, since most don't actually add new properties and simply rely on the message.
However, if your custom exception class has custom properties, then it MUST override ISerializable.GetObjectData() (and don't forget to call the base one), and you MUST unpack those properties in your serialization constructor.
While testing the solution I found out that something went wrong after the custom exception was returned to the orchestration. All information was present in the object but the messages could not be retrieved. I was puzzled. It looked like something in the serialization/deserialization process of the XLANGMessage object failed, but if one object should be serializable it should be this object. Right?
Further research showed that the XLANGMessage object was serialized/deserialized ok, but the XLANGPart object wasn't. This resulted in a correct XLANGMessage structure, with the correct number of parts in it, but with empty content. As a last resort I posted a question on the MSDN forum.
Within a day I had the solution. It turned out that the XLANGMessage property containing the XLANGParts data wasn't public so with binary serialization it was skipped. That at least explained this behavior, but how to solve it? In fact that was also in the reply (thanks Douglas Marsh) and in the Tomas Restrepo blog. You have to manually get the parts that aren't serializable and put them in the SerializationInfoStore in the GetObjectData method. Like this:
public override void GetObjectData(SerializationInfo info, StreamingContext context)When deserializing you can get them back in the serialization constructor, like this:
if (info != null)
info.AddValue("Fault", this.Fault, typeof(XLANGMessage));
// Get the message parts, they aren't serializable so we have to do it by hand
// Get the contents of the parts, convert them to a byte and add them to the store
if (this.Fault != null)
info.AddValue("NumberOfFaultParts", this.Fault.Count, typeof(Int32));
for (int i = 0; i < this.Fault.Count; i++)
info.AddValue("FaultMsgPart" + i, Helper.XmlDocumentToByteArray((XmlDocument)this.Fault[i].RetrieveAs(typeof(XmlDocument))), typeof(byte));
protected MyCustomException(SerializationInfo info, StreamingContext ctxt)
: base(info, ctxt)
if (info != null)
// get all the public members
this.Fault = (XLANGMessage) info.GetValue("Fault", typeof(XLANGMessage));
// Get the message parts, they aren't serializable
// This has to be in a try block, because the 'NumberOfFaultsParts' isn't always there and there is no way of knowing in advance
int faultPartsCnt = info.GetInt32("NumberOfFaultParts");
for (int i = 0; i < faultPartsCnt; i++)
XmlDocument doc = Helper.ByteArrayToXmlDocument((byte)info.GetValue("FaultMsgPart" + i, typeof(byte)));
catch (Exception ex)
Trace.WriteLine("XLANGPart serialization error: ", ex.Message);
So after all it wasn't that difficult at all, but isn't that always the case?? Thanks to everybody helping me.
On a blogpost by Yossi Dahan I read about a BizTalk tool I didn't know about: MsgBoxViewer
Via Google I couldn't find much about it so I decided to unpack it and try it. This was a very easy process because it doesn't require any installation, just unpack and run the GUI.
It appears to be a tool able to gather information about the status of your BizTalk environment, also with 'Best Practices Analyzer'-like features.
The name of the tool suspects that only the MessageBox is checked, and it does show the condition of your database, but the tool can do much much more.
The tool is written by Jean-Pierre Auconie, a Tech Lead in the European MS BizTalk Support team. He started developing this tool to ease the process of getting information from customers while trying to solve their problems.
Take a look at it yourself, it can be downloaded here.