Skip to the content.

Transport Binding

Downloads The code samples used in this user guide have been made available in the Be.Stateless.BizTalk.Factory.Samples GitHub repository.

Let us configure the transport of our sample Microsoft BizTalk Server® Receive Locations and Send Ports. Depending on whether this is a receive location or a send port, the developer will have to configure either an inbound or an outbound adapter.

Transport Adapter

Important There is much more to be said about the configuration of transport adapters and the developer is invited to read the dedicated section about the Adapters for more information.

API wise, configuring the transport adapter of either a receive location or a send port is almost identical. There is however no risk that a developer could inadvertently configure an outbound adapter for a receive location —or, conversely, an inbound adapter for a send port— as this is prevented by the Binding DSL at its core, i.e. the C# would not even compile.

For the illustration’s sake, let us configure the transport adapter of our Bribe Receive Location. You should notice a familiar Binding DSL pattern right now: the constructor is given a configuration lambda.

Transport.Adapter = new FileAdapter.Inbound(
  a => {
    a.ReceiveFolder = @"c:\file\evil\bribes";
    a.FileMask = "*.xml";
    a.RenameReceivedFiles = true;
  });

The configuration of the transport adapter of our inline Credit Note Receive Location is very similar:

rl.Transport.Adapter = new FileAdapter.Inbound(
  a => {
    a.ReceiveFolder = @"c:\file\billing\credits";
  }
);

Remark We can rely on the configuration properties’ default values and don’t have to configure all of them for any given adapter. Anyway, should we forget to configure a mandatory property, this would be caught by the ApplicationFixture’s GenerateApplicationBinding test. Let us suppose we forget to configure the ReceiveFolder, then the test would fail complaining that it Did not expect any exception, but found Be.Stateless.BizTalk.Dsl.Binding.BindingException with message “[Credit Note Receive Location] Receive Location’s Transport is not valid: Inbound file adapter has no source folder.”

As illustrated by the following code excerpt, configuring the outbound adapter is unsurprisingly very similar too:

Transport.Adapter = new FileAdapter.Outbound(
  a => {
    a.DestinationFolder = @"c:\file\tax-evasion";
  }
);

Transport Host

Configuring the transport host of any receive location or send port really is a no brainer. For our inline Credit Note Receive Location this would look like:

rl.Transport.Host = "BizTalkServerApplication";

While for our separate Bribe Receive Location that would be:

Transport.Host = "BizTalkServerApplication";

Receive Location’s Transport Specifics

Schedules and Service Windows

BizTalk.Factory’s Binding DSL exposes a rich API to configure all the aspects of receive location’s Schedule and ServiceWindow, as illustrated by the following examples.

With a non recurring service window:

Transport.Schedule = new Schedule {
  AutomaticallyAdjustForDaylightSavingTime = true,
  StartDate = new DateTime(2022, 1, 20),
  StopDate = new DateTime(2022, 2, 14),
  TimeZone = TimeZoneInfo.Utc,
  ServiceWindow = RecurringServiceWindow.None
}

With a daily recurring service window:

Transport.Schedule = new Schedule {
  ...
  ServiceWindow = new DailyServiceWindow {
    StartTime = new Time(8, 0),
    StopTime = new Time(20, 0),
    From = new DateTime(2022, 1, 20),
    Interval = 4
  }
}

With a weekly recurring service window:

Transport.Schedule = new Schedule {
  ...
  ServiceWindow = new WeeklyServiceWindow {
    StartTime = new Time(8, 0),
    StopTime = new Time(20, 0),
    From = new DateTime(2022, 1, 20),
    Interval = 2,
    WeekDays = BtsDayOfWeek.Monday | BtsDayOfWeek.Friday
  }
}

With a monthly recurring service window based on calendar days:

Transport.Schedule = new Schedule {
  ...
  ServiceWindow = new CalendricalMonthlyServiceWindow {
    StartTime = new Time(8, 0),
    StopTime = new Time(20, 0),
    Months = Month.January | Month.April | Month.July | Month.October,
    Days = MonthDay.Day01 | MonthDay.Day08 | MonthDay.Day15 | MonthDay.Day22 | MonthDay.Day29,
    OnLastDay = true
  }
}

With a monthly recurring service window based on ordinal days:

Transport.Schedule = new Schedule {
  ...
  ServiceWindow = new OrdinalMonthlyServiceWindow {
    StartTime = new Time(8, 0),
    StopTime = new Time(20, 0),
    Months = Month.January | Month.March | Month.June,
    Ordinality = OrdinalType.First,
    WeekDays = BtsDayOfWeek.Monday | BtsDayOfWeek.Friday
  }
}

Remark Custom Schedule and ServiceWindow classes could be written in an environment sensitive way —see Environment Overrides— and will be given the opportunity to provide different configurations according to the target environments for which the application bindings are generated.

Remark When trying to compile some of the previous samples, the compiler might complain that The type ‘BtsDayOfWeek’ is defined in an assembly that is not referenced. You must add a reference to assembly ‘Microsoft.BizTalk.ExplorerOM, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’. In this case, the developer should reference the BizTalk.Server.2020.Utilities NuGet package.

In doing so the developer might causes another compilation to arise, namely, The type ‘BtsDayOfWeek’ exists in both ‘Microsoft.BizTalk.ExplorerOM, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’ and ‘Microsoft.BizTalk.Messaging, Version=3 .0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’.

Fixing this problem is more involved and requires the developer to define a C# extern alias. Assigning an alias to a specific assembly that is part of a multi-assembly NuGet package is not supported by Visual Studio user interface. It is however fairly easy to edit the project file, i.e. Org.Anization.Accounting.Bindings.csproj, and add the following excerpt:

<ItemGroup>
  <Reference Include="Microsoft.BizTalk.ExplorerOM">
     <Aliases>ExplorerOM</Aliases>
  </Reference>
</ItemGroup>

and rewrite the source file’s using directive as follows —notice the Explorer:: prefix:

using ExplorerOM::Microsoft.BizTalk.BtsScheduleHelper;

Send Port’s Transport Specifics

Retry Policies

A send port’s transport expose a configurable retry feature. The BizTalk.Factory’s Binding DSL API surfaces it as a RetryPolicy class, which exposes 2 properties:

Transport.RetryPolicy = new RetryPolicy {
  Count = 3,
  Interval = TimeSpan.FromHours(2)
};

Every seasoned Microsoft BizTalk Server® developer knows that there is a default retry policy that every send port inherits. Faithful to this principle, every send port declared and configured through BizTalk.Factory’s Binding DSL will have the same default retry policy unless otherwise specified. This default policy is explicitly available through the static Default property of the RetryPolicy class.

using Be.Stateless.BizTalk.Dsl.Binding;

Transport.RetryPolicy = RetryPolicy.Default;

Remark For the record, the RetryPolicy.Default does not have hardcoded Count and Interval values but rather fetches them from the configuration classes being part of the native Microsoft BizTalk Server® API.

Environment Sensitive Retry Policies

Recall that a custom RetryPolicy class could be written in an environment sensitive way —see Environment Overrides— so as to be given the opportunity to provide different configurations according to the target environments for which the application bindings are generated.

BizTalk.Factory’s Binding DSL has done precisely that and comes with a predefined set of environment sensitive RetryPolicies made available together with its Naming Convention —see Be.Stateless.BizTalk.Dsl.Binding.Conventions NuGet package. BizTalk.Factory defines three not so arbitrary retry policies:

Each of these policies is environment sensitive in its own way:

The whole idea behind these policies is that the developer expresses his actual intent in the code, but the configuration is smart enough to avoid long periods of message delivery attempts in non production environments, therefore speeding up the tests that can rapidly became operationally painful otherwise.

Service Windows

A service window restricts the send port to work during certain hours of the day. It is exposed by the send port’s ServiceWindow property, which is a class exposing 2 properties:

Should you wonder how to configure a service window and instantiate a Time type, the intellisense will guide you through.

Transport.ServiceWindow = new ServiceWindow {
  StartTime = new Time(11, 12, 13),
  StopTime = new Time(23, 22, 21)
};

Remark A custom ServiceWindow could be written in an environment sensitive way —see Environment Overrides— and will be given the opportunity to provide different configurations according to the target environments for which the application bindings are generated.