In the BizTalk schema editor, you manage both of these types of property promotion by using the Promote Properties dialog box, which you access by using the Promote Properties property o
Trang 1• Performance: Large message properties cannot be “streamed” and must be entirely
loaded into memory by the runtime This will become an issue if you write large valuesfor message properties into the message context
• Overwriting of promoted properties: If you have promoted a property to the message
context, and you issue a context write operation, the property is no longer promoted
• Dealing with Nulls: Null properties are not persisted to the context If you set a
prop-erty’s value to Null, it will no longer exist, and you cannot see a context property in theHAT with a value of Null
Distinguished Fields
There are two types of property promotion: distinguished fields and property fields The latter
type uses property schemas In the BizTalk schema editor, you manage both of these types of
property promotion by using the Promote Properties dialog box, which you access by using the
Promote Properties property of the Schema node Distinguished fields are only useful when
they are accessed within orchestration Promoted properties can be accessed either in
orches-trations or from custom code, routing, and pipelines
Distinguished fields, on the other hand, cannot be used for routing and are only used bythe orchestration engine When dealing with large messages, this can save significant server
processing, as the engine would need to use XPath expressions to search through the
docu-ment to find the piece of data that it needs each time the expression is evaluated This way, the
data is loaded once when the document is parsed by the runtime engine Distinguished fields
are used within orchestrations to move required elements into the context and only read the
context property within the orchestration without having to load the entire document into
memory Distinguished fields also offer nice IntelliSense capabilities within the orchestration
expression editor and message assignment shapes
Depending on the type of access that is needed, you can choose to create either promotedproperties or distinguished fields depending on how the property will be used Distinguished
fields do not require the creation of a corresponding property schema
Using Port Filters and Content-Based Routing
As stated in the previous section, subscriptions and context properties are integral to the
mes-saging subsystem Property schemas are the mechanism by which the context properties are
stored in the message context When creating schemas, you can define a property schema that
will hold any custom properties that will be used for routing the inbound message To create a
custom property schema, you need to create a schema and a property schema to hold the
properties In order to move a value from the data of the message into the context, it is
neces-sary to “promote” the property into the context property bag The BizTalk Message Bus
auto-matically promotes system-level properties from the system property namespaces, depending
on the type of inbound and outbound transports that are being used Each adapter will require
and hence promote values that it needs to send and receive the message according to its
par-ticular protocol
In the schema definition of the message, property promotion is done by first associatingthe property schema to the message and choosing the property to promote Most architects
Trang 2don’t understand how messages are routed within the product or how to use the propertyschemas to affect the subscription Exercise 3-1 will show you how you can use the propertypromotion to implement routing logic.
Exercise 3-1: Using Custom Promoted Properties to Route Messages
Let’s continue our example from Chapter 2 of an organization that takes inbound documents from multiple sources,normalizes them to a canonical input schema, and sends them to different outbound locations Assume that thereare three systems: a web site, a POS application, and an automated FTP upload location Each of these locationstakes a different schema and must map it to internal schema This mapped message then needs to be sent to theERP system However, as an added piece of functionality, documents from the web site need to be sent to a sepa-rate location as well, and documents from the POS system need to be sent to a file system directory so they can
be batch uploaded at a later time Figures 3-3 and 3-4 define the schema for the internal messages and a possiblesolution architecture
Figure 3-3.Internal order request schema
Trang 3The requirements for this solution are quite common in most BizTalk projects, and most new BizTalk architects
design it incorrectly Generally those unfamiliar with the subscription nature of the Message Bus will tend to build
an orchestration that has logical ports directly bound to the physical ports The orchestration would then use
Decide shapes to send the message to the appropriate send port, which will then send the message on its way
An even worse solution is to create three orchestrations, each of which receives the inbound message directly
from the receive location, executes the map from within the orchestration, and then has a static bound port that
is bound to the send port from within the orchestration This problem requires only messaging to be solved No
orchestrations should be created here since no business logic is needed Routing the message to the correct
location is not business logic, and as such, an orchestration is not the correct tool to use from the BizTalk Server
toolbox
To implement the routing logic, subscriptions need to be created that allow the inbound message, once it has been
mapped, to be sent to the correct port Here, you create filters based on the MessageType context property that
allow the Messaging Engine to automatically forward any messages of type http://ABC.FulFillment
BizTalk.Schemas.OrderSchema#Order to the ERP system The filter of the port will modify the subscription
in the Messagebox accordingly In the filter properties of the ERPSendPort, the expression shown in Figure 3-5 will
be present
Figure 3-4.Solution architecture
Trang 4You still have not seen how to solve the problem of differentiating messages that are received from each of thethree separate order producing systems Notice that the internal schema definition includes an element that willallow you to store that data should it be available, but there are two problems: a) how do you get the value in thiselement, and b) how can you route messages based on it For adding this value into the data document, you usethe inbound map defined on the receive port All you need to do is create a map from the external schema to theinternal schema and assign a constant value for the SourceSystem element.
To allow you to route on the SourceSystem property, you need to create a property schema to define what erties you want to store in the context and to allow the Messaging Engine to promote the value from the data inyour inbound document To do this, add a new item to the schema project: in the list of BizTalk project items,choose Property Schema Add an attribute to the schema called SourceSystem This can be seen in Figure 3-6.Figure 3-7 shows the schema for the internal order property schema as viewed in the BizTalk schema editor
prop-Figure 3-5.ERPSendPort properties
Trang 5Figure 3-6.Web site to internal schema map
Figure 3-7.Order property schema
Trang 6The next step is to associate the custom property schema to the internal order schema To do this, right-click theSourceSystem element in the internal order property schema and choose Promotions ➤Show Promotions This
is demonstrated in Figure 3-8 Next, click the Promoted Properties tab and click the open folder icon
Once you have chosen OrderPropertySchema, highlight the SourceSystem element on the left and click the Addassociate button This will add the element to the list of promoted properties Notice that since there is only oneproperty defined in the property schema, the editor automatically associates this field with the SourceSystemproperty in the property schema This can be seen in Figure 3-9
Compile the project and deploy it to the Management Database Once the schema’s assembly is deployed to theManagement Database, it will automatically be available in the list of properties in a ports filter If you create a newsend port and want to only send documents from the web site, you can add it as a filter, and this will automaticallyupdate the subscription as shown in Figure 3-10
Another important fact to note is that in this situation, you only need to create one receive port with three receivelocations You also need to create three maps and add them each to the transforms on the port The pipeline willexamine the inbound schema for each map and send the inbound document to the correct map If no port has asubscription for a matching inbound message type, an error will occur, and the message will become suspended
Figure 3-8.Property Schema Type Picker
Trang 7Figure 3-9.Manually promoting the SourceSystem property
Figure 3-10.Routing based on a custom promoted property
Trang 8Using System Property Schemas
As mentioned previously, a number of system property schemas come with the product Most
of these property schemas exist to support each of the transports and adapters included withthe product out of the box Most of the time, each new transport or application adapter willbring with it a new property schema that is used to define any custom metadata needed toprocess the message by the adapter Each of the system property schemas is included in thebase assembly Microsoft.BizTalk.GlobalPropertySchemas.dll Referencing this assembly from
a BizTalk project in Visual Studio will allow you to access each of the schemas as you wouldwith any other schema type
Modifying Values from System Property Schemas: Simple Example
So at this point many people ask the question, “Big deal, I can modify values that BizTalk uses,
so why would I need this ability?” In order to fully understand why the creation of propertyschemas becomes an invaluable tool, let’s look at a simple example Continuing with the sce-nario from Exercise 3-1, let’s assume that an order received from the bulk order system needs
to be written to a file location on a server within the organization Let’s also assume that weneed to dynamically modify the name of this file depending on some value from the message:the customer ID plus the character “#” and the total amount of the order
At first, modifying the file name based on a message value seems like an easy thing to do,but it becomes a little more complicated when you look at it In reality, there are three solu-tions to the problem Solution A would be to use an orchestration with a dynamic port andwithin the orchestration use some XPath expressions to get the data you need from the mes-sage; dynamically set the address of the file adapter; and send the file to the dynamic port.However, in reality there is a cost to doing this First, you are breaking one of the cardinal rules
of BizTalk—you are using orchestrations to do routing logic Second, you have an tion that is exclusively bound to a port and has to be deployed, enlisted, and started with theport it is bound to.3Third, if this were a large message, using XPath will force the orchestrationengine to load the entire document into memory in order to parse out the values from theXPath expression.4
orchestra-Solution B is to use the BizTalk Messaging Engine and have it do the work for you Toimplement this solution, you use the macro functionality to write the message in the sendport You need to modify your internal order schema so that there is a new element calledOutBoundName or something similar, and you need somewhere to promote this property to For this, use the file adapter property schema In the internal order schema, there is an ele-ment called ReceivedFileName What you do is modify the BulkOrderToInternal.btm map sothat the value of the CustomerID along with the total is concatenated into your new element
in the internal schema You still have to promote the CustomerID property into the context
3 In later chapters, we will discuss orchestrations with direct-bound ports (i.e., not bound to a physicalport, but bound to the Messagebox database) vs orchestrations with static/dynamic bindings Thereare pros and cons to each, but there are more pros than cons to a direct port, and generally they arepreferable to static or dynamically bound ports
4 We could use distinguished properties to get around this The orchestration engine will not load theentire document if the property were distinguished As stated previously, these would be written intothe context when the message is processed by the Messaging Engine However, the point is that usingXPath in orchestrations is costly, especially on large messages
Trang 9To do that, in the Property Promotions tab of the schema, add a reference to the file adapter’s
property schema
The next step is to create a send port that subscribes to the correct message type, setthe outbound destination in the send port to the desired directory, and set the file name
to be %sourcefilename% The BizTalk Messaging Engine will use whatever value is stored
in the ReceivedFileName message context property when writing this value out Since you
have changed it and promoted it, the engine will use your new value instead of the original
one as shown in Figure 3-11
Solution C is to create a custom pipeline component, add it to a stage in a custom receivepipeline, and have it promote the value you want into the context using the message API The
code would look something like the following:
Private Sub PromoteProperties(ByVal message As IBaseMessage, ByVal CustomerID As _
String, ByVal OrderTotal As Decimal)
Dim BTSFilePropertiesNamespace As String = _
"http://schemas.microsoft.com/BizTalk/2003/file-properties"
Dim FileName As String
'Get the original directory the file was received from by reading the message _
context and creating a FileInfo object
Dim FileInfoObject As new
System.IO.FileInfo(message.Context.Read("ReceivedFileName", _
BTSFileropertiesNamespace))
Figure 3-11.Promoting a value using a system property namespace
Trang 10'Replace the original name with the new one
FileName = FileInfoObject.DirectoryName + "\\ + CustomerID + "#" + _
Mes-In this scenario, there would be no server downtime and few configuration changes required.The trade-off is that you would have additional custom logic and custom assemblies that must
be maintained and deployed with the solution as a whole
Modifying Values from System Property Schemas: Extended Example
Now that you see a simplistic usage of modifying a system property, we will show you thing a little more interesting Continuing with the previous example, assume that you need tosend information to your ERP system with messages received from the web site Also assumethat there have been performance problems calling the ERP solution Currently the ERP systemuses a custom API written in VB 6.0 and exposed through COM+ objects You need to trackhow long these calls are taking, but you want the information included within the Messageboxand you want it bundled with all the other tracking information that is stored in the databaseand accessible through HAT for the server administrators You also want individual trackinginformation per message so that you can correlate what types of transactions are taking themost time
some-Assume that the code to call the API is fixed and cannot be modified Due to architecturallimitations, you also cannot impose a wrapper (i.e., web service or custom adapter), you mustcall the API directly as you would be normally, and these calls must be synchronous becausethe API will not support asynchronous calls due to threading issues Currently, the API iscalled from an Expression shape inside an orchestration, and depending on a series of returnvalues, different business logic is executed As an added bonus, the administrators want acopy of all messages that take more than 5 seconds to process to be sent to a drop locationwhere those messages can be viewed offline The development team does not want any majorlogic modifications to the existing receive ports/send ports/orchestrations to implement thelogging logic (i.e., you can’t store the tracking value somewhere and have the orchestrationinsert a Decide shape that sends a copy to the send port) Also, message tracking is not enabled,since this is a production system, and the administrators do not want to decrease the per-formance of the system any further
Trang 11Now that your hands are a little more tied, the options are becoming a bit limited Mostpeople at this point will want to modify the orchestration that logs information either to the
event log or to a performance counter, but that still doesn’t address the problem of how you
can associate a message that you processed with its timing values and have them show up
somehow in HAT, nor does it address the problem of how to properly route on those timing
values Also, this breaks one of the cardinal rules: you use orchestrations for something other
than business logic Another option would be to create some custom tracking elements in the
document and write these from within the orchestration, but that would require a schema
change and some new code Luckily, there is a better way, and it only requires five lines of
code be inserted into the orchestration along with two variables
BizTalk includes a tracking property schema within the product Although this schema isvery poorly documented (as in not at all), it is possible to write values to it The property schema
is used to define context properties that adapters can write to that will aid in the very type of
sce-nario we’re discussing now The fact that we can write values to the tracking property schema
really doesn’t help since tracking is not enabled Also, since the performance bottleneck in this
scenario is not based on an adapter, the tracking information is not accurate However, you can
still use the property schema to write information to the context from within the orchestration
that will help you as shown in Figure 3-12
The system property schema is in the bts-messagetracking-properties.xsd schema file Bydefault, this schema is populated with values from adapters, but there is nothing that says you
can’t put your own values in here Also, since the schema is a property schema, the values will
be available for routing The problem of how you can configure your send port to automatic
pickup times that are greater than 5 seconds has now been solved What you can do is create
a little expression in the expression editor that gets the current Now() time and substracts it
from the time that the operation finished The StartTime variable is a local variable defined
as a System.DateTime that is initialized to the current time within the orchestration Since
the result will be of type System.Timespan you cannot simply store it in the property
MessageTracking.AdapterTransmitEndTime since that property is of type System.DateTime
There is another property called MessageTracking.ActivityIdentity that is of type string,
which will allow you to store anything you want You simply store your computed time in that
property and use it to route your messages as shown in Figure 3-13
Figure 3-12.Orchestration expression
Trang 12Custom Properties and Orchestration Routing
As demonstrated earlier, custom properties can be very useful in routing scenarios The ous example showed how to route the message to an orchestration based on a custom prop-erty and a subscription created via the filter expression If you were routing this message to anorchestration based on a filter defined in the receive port of the orchestration, you would getthe following error:
previ-"message data property 'ABCPropertySchema.CustomProperty' does not exist in
messagetype 'myOrchestrationMessage'"
What is happening in this case is that the orchestration engine is examining the messagewithin the orchestration and throwing an error stating that the property you wish to route ondoes not exist in the message Typically the engine is correct; however, in this case, you knowthat this is okay The solution is to tell the engine that data for your property will not comefrom the message and that you will provide it
To fix this, you need to set the Property Schema Base for the property under the Referencesection of the schema editor as shown in Figure 3-14
Figure 3-13.Send port filter expression
Trang 13To the runtime, this determines what the base type will be used for in the property inquestion The base type for the property will be used to determine where the data for the
property will come from The possible values for this are
• MessageDataPropertyBase (Default): The data in this field will come from a message.
• MessageContextPropertyBase: The data in this field may not exist in a message (i.e.,
it could be prompted inside a custom pipeline) The values will not be inside themessage
• PartContextPropertyBase: This tells the runtime that the value for the property will
be a part of the MessagePart context
The key takeaway is that if you are promoting properties that do not exist in the message,
be sure to set the proper base type for the property (i.e., MessageContextPropertyBase)
As you can see, using system properties can solve a number of rather complex scenarioswith very little effort This is explored in further detail later on in the book
Tracking and Message Management
Now that you have seen how BizTalk stores, routes, and publishes messages, the next step is
to understand how those messages can be tracked and what happens to them once they have
been processed Each subscriber of a particular message references the same, single copy of
Figure 3-14.Changing the base type for a property
Trang 14that message This approach requires that a reference counter be kept for all messages flowingthrough the system Although this minimizes storage, it requires that the messages be cleaned
up once their reference counters reach 0 To accomplish this, the product includes a set of SQLAgent jobs that perform garbage collection for zero-reference-count messages and messageparts The stored procedures that handle garbage collection are as follows:
• MessageBox_Message_Cleanup_BizTalkMsgBoxDb: Deletes all messages that have
no references by any subscribers
• MessageBox_Parts_Cleanup_BizTalkMsgBoxDb: Deletes all messages that have no
references by any messages Remember what we stated at the beginning of thechapter—messages are made up of one or more message parts that contain the actualmessage data
• PurgeSubscriptionsJob_BizTalkMsgBoxDb: Deletes unused subscription predicates
leftover from from system-created subscriptions
• MessageBox_DeadProcesses_Cleanup_BizTalkMsgBoxDb: Executed when the
run-time detects that a server has crashed This frees the work that the server was working
on so another machine within the group can process it
• TrackedMessages_Copy_BizTalkMsgBoxDb: Copies tracked message bodies from
the Messaging Engine spool tables into the tracking spool tables in the Messageboxdatabase
• TrackingSpool_Cleanup_BizTalkMsgBoxDb: Reverses the database table that the
TrackedMessages_Copy_BizTalkMsgBoxDb SQL Server Agent job writes to
The first two items from the preceding list are used to keep garbage messages removedfrom the Messagebox When executed, they search the messages and message parts within theMessagebox looking for messages with a reference count of zero The stored procedures alsocheck for parts that are not referenced by any messages and remove those as well Once mes-sages are ready to be removed, they are moved to the BizTalk Tracking Database These twojobs are executed from the machine that hosts SQL Server In order for these jobs to run, theSQL Server Agent needs to be running If SQL Server Agent isn’t running, tracked messagebodies will never be offloaded to the Tracking Database, and hence the Messagebox will grow
As the database grows, performance will suffer, as the number of messages grows unchecked.This is due to the fact that the Message Agent that is running within each BizTalk host will becalling a stored procedure that searches through each of the messages in the Messageboxlooking for messages with matching subscription information
To keep the Messagebox as empty as possible, the tracking subsystem will move pleted messages to the Tracking Database on a periodic basis The Tracking Database is also
com-is where the HAT queries for data and dcom-isplays its tracking information Thcom-is com-is accomplcom-ished
by a BizTalk host that has been tagged as a “tracking” host This is an option in the Host erties pages
Prop-Handling Failed Messages and Errors
In BizTalk 2004, being able to simply get a copy of a suspended message was a pain Therewere a number of very clever design patterns to allow you to get at suspended messages, but
Trang 15each of them required either custom orchestrations or pipeline components to subscribe to
the negative acknowledgements (NACKS) in order to look up the suspended message that you
were after and route that message dynamically to some endpoint
In BizTalk Server 2006, getting at suspended messages is a simple problem to resolve TheBizTalk product team added a set of context properties that are available to be subscribed on
and routed to Error handling context properties are defined within the http://schemas
microsoft.com/BizTalk/2005/error-report property schema The new context properties are
signal the runtime engine to generate the routing failure message and publish it to the
Messagebox Since the message is published, there needs to be a subscription available to
receive the routing failure message To that end, you can create an orchestration that is
direct-bound5to the Messagebox through a receive port The Receive shape in the orchestration will
have a filter criteria specified that sets the subscription information so that it will receive all
failed routing messages
To implement the routing, the filter expression needs to be set to “ErrorReport.ErrorType
== Failed Message” as shown in Figure 3-16
This will cause the subscription to be written that will receive all suspended messages
From here, once you have a copy of the failed message within the orchestration, you can send
it wherever you need An example would be to have the orchestration send the message to an
e-mail address or to an offline database for examination All these options will be quite easy to
implement since the message has been parsed and routed to the orchestration
5 Direct binding refers to orchestration ports that are not specifically bound to any physical port but
will receive messages solely based on the subscription As you saw in the “Subscriptions” subsection
in the chapter, all this means is that there is no receive port or transport ID information written to thesubscription
Trang 16Figure 3-15.Receive port configuration
Figure 3-16.Orchestration Receive shape filter
Trang 17The BizTalk Management Database
Up until this point, our discussions regarding BizTalk schemas, deployment, and namespaces
have been in the practical sense We have not discussed where schemas are actually stored, or
what is happening within BizTalk when a new schema is deployed For that, we need to
under-stand the BizTalk Management Database Unlike the Messagebox, the Management Database
is not used to store messages and is not considered to be “working storage.” The Management
Database is where most configuration and system-level information is stored and accessed
from within BizTalk It is important to understand what’s going on behind the scenes when
you perform administrative actions using either UI tools or the ExplorerOM/WMI API,6as it
will give you a good understanding as to how BizTalk artifacts are tied together within the
product Such understanding may save time when dealing with specific issues such as “Why
isn’t my schema namespace resolving?” or “What version of my schema is this document
orchestration Open Visual Studio and create an empty solution Name the solution
Explor-erWMI Add two BizTalk projects to the solution and name them Schemas and Orchestrations
6 ExplorerOM is the primary API that you will use to work with BizTalk artifacts from within code WMI
is the Windows Management Instrumentation technology we introduced in Chapter 1 For a completediscussion of these techologies as they relate to BizTalk, see Chapter 10
7 We have included the ExplorerOM code within this chapter for easy reference For a complete
discus-sion of deploying, managing, and supporting BizTalk using the ExplorerOM API, see Chapter 10
Trang 18Choose Add a New Project Item, then choose schema file Name it TestSchema Switch
to the Properties window, select the root node, and change the Node Name property toExplorerWMI as shown in Figure 3-17
Now switch to Solution Explorer, right-click the Schema project, and select Build BizTalkcompiles the XSD schema and places class definitions in its Schemas.dll assembly You can see
it in the project’s output directory If you are curious, you can load the generated assemblySchemas.dll file into a freeware tool like the NET Assembly Viewer from Ralf Reiterer8to checkout the generated NET class definition matching our TestSchema.xsd schema as shown inFigure 3-18
Switch to the Orchestrations project, add an orchestration, and configure it to passthrough any received messages to a file-based send port as shown in Figure 3-19
Figure 3-17.ExplorerWMI project within Visual Studio 2005
8 http://dotnet.jku.at/applications/course03/Reiterer/
Trang 19Figure 3-18 .NET Assembly Viewer
Figure 3-19.Simple pass-through orchestration
Trang 20Right-click the Orchestrations project and select the Build menu item As you may haveguessed, the XLANG compiler compiles the orchestration into a C# class and calls the standardcsc.exe C# compiler This in turn generates the Orchestrations.dll assembly If you want to look
at our generated C# code to see how the orchestration class interacts with the orchestration
engine, you can use an undocumented registry setting Add a registry key named BizTalkProject
at HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0 for Visual Studio 2005 If youare using BizTalk 2004 and Visual Studio NET 2003, the key is HKEY_CURRENT_USER\
Software\Microsoft\VisualStudio\7.1 Next, create a DWORD value named GenerateCSFiles
and set it to 1 If you rebuild your project, you will see C# files in your project directory
Now that all the preliminary steps are complete, you are ready to deploy the solution.Choose the Build menu and select Deploy Solution Executing the Deploy command withinVisual Studio puts assemblies into the GAC (if this option is selected in the project settings)and also updates the Management Database The first table you want to examine within theBizTalk Management Database is bts_Assembly This table contains information about systemassemblies and assemblies specific to custom applications They are distinguished by annSystemAssembly field A value of 1 in this column indicates that assembly is a system assem-bly As you can see in the last row, the deployment procedure put information about theSchemas and Orchestrations assemblies into this table as shown in Figure 3-20
Now switch to the bt_DocumentSpec table and let’s look at this table in more detail Thebt_DocumentSpec table is very important and will be the first place to look when resolvingBizTalk error messages like the ones mentioned previously
Next, you’ll figure out what your message type is As stated previously in the chapter, amessage type within a BizTalk solution is a concatenation of target namespace property androot node name When you add a new schema file to your project, Visual Studio automaticallysets the target namespace to http://[ProjectName].[SchemaFileName] The schema’s rootnode name is always preset to Root When you deploy your project containing XSD schemas,the deployment procedure puts the message types into and references the assembly contain-ing the NET class definitions in bt_DocumentSchemas
Figure 3-20.bts_Assemblies table
Trang 21Since you changed the root node name in your project to ExplorerWMI, the message typewill be http://Schemas.TestSchema#ExplorerWMI.
Open the SQL Server Management Studio and run the query shown in Figure 3-21
The output of this query confirms that you defined a new message of type http://
Schemas.TestSchema#ExplorerWMI, and the class Schemas.TestSchema is representing your
schema Its location is in the assembly Schemas, version 1.0.0.0
Upon startup, the BizTalk runtime caches this table in memory When a Receive Adapterpasses an inbound message to a receive pipeline, it first constructs the message type by con-
catenating the namespace and root node name of the incoming document It then checks
whether the message type is uniquely presented in the bt_DocumentSpec table If the check
is successful, the receive pipeline proceeds with further execution; if not, you will get an error
message similar to the ones we presented at the beginning of this section The bt_
DocumentSpec table will most likely be your first place to look when addressing issues
relating to resolving message types
Since Visual Studio automatically creates a unique namespace for document tion, you shouldn’t run into problems But if for whatever reason you change Target Name-
specifica-space and Root Node Name properties manually, you have to be careful not to create schemas
with conflicting namespaces
There is another situation you should be aware of that could potentially lead to problems
While working on different projects, we have seen developers make the same mistake and then
spend hours trying to figure out what’s going on If the schema namespaces are not set up
prop-erly, BizTalk will bounce incoming messages, stating that multiple schemas are matching the
same message type Here is how this might happen and what you can do to address it
As you may already know, the BizTalk programming model is quite flexible, especiallywhen it comes to message type conversion When you call methods located in external NET
assemblies from your orchestration and pass the BizTalk message to those methods, you most
likely pass the message as either a System.Xml.XmlDocument type or a
Microsoft.XLANGs.BaseTypes type You can then extract the message in the form of a
well-typed NET class, which is very convenient The inverse applies to when you need to create
a new message inside your NET code and return it to your orchestration In your
orchestra-tion inside a Construct Message shape, you can call a method that returns a NET class
Figure 3-21.SQL Server Management Studio query
Trang 22representing an orchestration message To generate this typed class, which matches your XSDschema, launch the Visual Studio command prompt and then run the following command:Xsd.exe /c TestSchema.xsd
This command will generate a file named TestSchema.cs containing the ExplorerWMIclass Include this file in your project and you can extract messages and create new ones as
a well-formed type as in Listing 3-2
Listing 3-2.Type Orchestration Message
Surely quite a handy technique, but like all conveniences, it can be a source of problems
if used indiscriminately When you declare a message in an orchestration, you are required tospecify what type of message it is (not to be confused with the message type routing property).You have four options:
to choose either when specifying the type of message when creating new orchestration sage variables
Trang 23mes-Add a new message to the orchestration, switch to the Properties View, and select theMessage Type combo box Expand the NET class branch and choose Select from Referenced
Assembly This will pop up a Select Artifact Type dialog as shown in Figure 3-22
Select the ExplorerWMI item in the right pane and compile and deploy the orchestration
Now open the SQL Server Management Studio and run the same query as shown in Figure 3-20
against the bt_DocumentSpec table and check out your results As you can see in Figure 3-23,
the document specification is deployed twice, pointing to different assemblies: one pointing to
the assembly created when you deployed XSD schemas, and another to the assembly
contain-ing classes produced by the XSD.EXE tool
Figure 3-22.Select Artifact Type dialog box
Figure 3-23.Multiple assemblies, same namespace
Trang 24As you see, the deployment procedure makes no attempts to check for possible tion and simply deploys everything as is If you now submit a document instance to thereceive location, you will get an error message in the Event Viewer.
duplica-Listing 3-3 is the code snippet showing how you can enumerate deployed assemblies andschemas The product documentation doesn’t mention the important properties of the Schemaclass, namely TargetNamespace and RootNode, which together constitute a message type So beaware that these properties are available
Listing 3-3.Enumerating Deployed Assemblies
static void Main(string[] args){
EnumerateSchemas();
Console.ReadKey();
}public static void EnumerateSchemas(){
BtsCatalogExplorer catalog = new BtsCatalogExplorer();
catalog.ConnectionString = "Server=.;InitialCatalog=BizTalkMgmtDb;Integrated Security=SSPI;";_
foreach (BtsAssembly assembly in catalog.Assemblies ){
foreach (Schema schema in assembly.Schemas){
Console.WriteLine("\t{0}#{1}",schema.TargetNameSpace,schema.RootName );
}}}}}
Trang 25Or you can access deployed schemas directly without enumerating assemblies first asshown in Listing 3-4.
Listing 3-4.Accessing Deployed Schemas Directly
static void Main(string[] args){
EnumerateSchemas();
Console.ReadKey();
}public static void EnumerateSchemas(){
BtsCatalogExplorer catalog = new BtsCatalogExplorer();
catalog.ConnectionString = "Server=.;InitialCatalog=BizTalkMgmtDb;Integrated Security=SSPI;";
foreach (Schema schema in catalog.Schemas){
Console.WriteLine("\t{0}#{1}",schema.TargetNameSpace,schema.RootName);
}}
}}