Ralph Romero

Blog

Serving a Static Website from Biztalk

Posted at — Jun 15, 2020

It is possible for Biztalk server to act directly as a basic web server serving up dynamic content. Of course you should consider when you need a full featured web server, but for basic cases such as serving up information to internal users, this can be a really simple solution.

The following shows how this is implemented.

Create Receive Location

Create a WCF-WebHttp request response receive location. Pipelines should be set to passthrough. The outbound headers should be set to ‘Content-Type: text/html’. No maps need to be set on the associated receive port.

You can configure to receive any parameters in the GET method and this isn’t any different from exposing a web API.

Processing Orchestration

Once the message is received, it must be processed through an orchestration. The important thing is that any transformation from an internal XML data format to HTML must occur within the orchestration and not on the receive port. This is because we need to bypass any XML validation applied at the port level and we do this by transforming in the orchestration.

In the orchestration, create a transform shape and map. It should take as input your XML data and use custom xslt to create a HTML document. The destination schema can be any schema file. It doesn’t matter what you use and this is why I said we need to bypass any validation. Your custom XSLT will then transform the document into well formed HTML. You can use inline CSS for any styling required.

Here is some sample XSLT to get you started.

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output omit-xml-declaration="yes" method="xml" standalone="yes" version="1.0" encoding="UTF-8" />
  <xsl:template match="/">
    <html>
      <head>
        <title>Sample Site</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous" />
        <style>
          li { text-indent: 60px }
          li.error { color: red }
          li.ok {color: green }
          h4.handle { text-indent: 30px }
        </style>
      </head>
      <body>
        <h1>Sample Site</h1>
        <p>
          <ul>
            <li>
              ID: <xsl:value-of select="/*[local-name()='Id']"/>
            </li>
            <li>
              Type: <xsl:value-of select="/*[local-name()='Type']"/>
            </li>
            <li>
              Status: <xsl:value-of select="/*[local-name()='Status']"/>
            </li>
          </ul>
        </p>
        <p>
        <h2>Things</h2>
          <xsl:for-each select="//*[local-name()='Thing']">
            <xsl:choose>
              <xsl:when test="substring(.,1,4)='handle'">
                <br />
                <h4 class="handle">
                  <xsl:value-of select="."/>
                </h4>
              </xsl:when>
              <xsl:when test="substring(.,1,5)='Error'">
                <li class="error">
                  <xsl:value-of select="."/>
                </li>
              </xsl:when>
              <xsl:when test="substring(.,1,10)='Ok'">
                <li class="ok">
                  <xsl:value-of select="."/>
                </li>
              </xsl:when>
              <xsl:otherwise>
                <li>
                  <xsl:value-of select="."/>
                </li>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:for-each>
        </p>
        <br />
        <h2>Output Internal XML</h2>
        <p>
          <textarea rows="40" cols="180" style="border:none;">
            <xsl:copy-of select="*"/>
          </textarea>
        </p>
      </body>
    </html>
  </xsl:template>
</xsl:stylesheet>