Omair Shakeel

Wednesday, December 25, 2013

Visual Studio & Biztalk Server compatibility


Just so that I do not forget later :)

Here is a list of Visual Studio & Biztalk Server compatibility:

Biztalk 2009 runs on CLR 2.0 (.NET 3.5)
Biztalk 2010 runs on CLR 4.0
Visual Studio 2010 supports .NET 4.0 & CLR 4.0
Visual Studio 2012 supports .NET 4.5 & CLR 4.5
Biztalk 2012 supports .NET 4.5 and works with Visual Studio 2012

Thursday, May 05, 2011

SgmlReader - converting HTML into a well formed XML


SgmlReader is a nice .NET library that converts an SGML document into a well formed XML. It has a built-in support for converting HTML as well.


One of our clients was sending us emails to our systems that were extracting the required information from those emails. The content type of their emails was HTML. The main job was to convert the HTML into an XML and parse the XML and extract the information that our system was looking for. Most of todays browsers and email clients are able to view content even if the HTML is not well formed. And HTML is not itself required to be well-closed / well-formed. 

Unclosed tags such as <br /> are acceptable. Also attributes without enclosing double quotes are also allowed such as
<div id=mDiv> </div> . Loading an HTML string into an XmlDocument will throw an exception. Free libraries such as SgmlReader can come into handy in such cases that can correct your ill-formed HTML into a well formed XML document.

SgmlReader is an XmlReader API over any SGML document. You can download it from here.

A common code example looks like this:

SgmlReader reader = new SgmlReader();
reader.DocType = "HTML";
reader.WhitespaceHandling = WhitespaceHandling.All;
reader.CaseFolding = CaseFolding.ToLower;

using (StringReader htmlStringReader = new StringReader(html))
{
    reader.InputStream = htmlStringReader;

    // Load the xml document
       XmlDocument document = new XmlDocument();
    document.PreserveWhitespace = true;
       document.XmlResolver = null;
       document.Load(reader);
}

Tuesday, May 03, 2011

Send HTML emails using BizTalk's SMTP adapter without orchestrations


This article explains how you can send HTML emails using BizTalk's SMTP adapter without the help of orchestrations. My problem was to just perform message routing to an external party at the ports, using orchestration would be an overkill-solution to this problem.

Initially it looks quite simple to do this. Just map your source message to an XHTML message that would be sent as an email by the SMTP adapter. But the problem is that the SMTP adapter automatically sets the content type to text/plain (or text/xml if the XML pipeline is selected). There is no ContentType property that you can set among the properties of the SMTP adapter. I googled for this and found out plenty of articles on sending html emails using the STMP adapter, but they were all using the orchestrations.

The job is pretty easy when you use an orchestration for this. All you need to do is set your email body as a RawString (Microsoft.Samples.BizTalk.XlangCustomFormatters.RawString) such as:
EmailMessage.Body = new Microsoft.Samples.BizTalk.XlangCustomFormatters.RawString(htmlstring);
and set the ContentType such as:
EmaiMessage.Body(Microsoft.XLANGs.BaseTypes.ContentType) = "text/html";

I need to do the same thing but without orchestrations. I decided to create my own custom pipeline component that would set the ContentType value during the Encode stage. Here is the following code of the pipeline component:

[ComponentCategory(CategoryTypes.CATID_PipelineComponent)]    [System.Runtime.InteropServices.Guid("CA9082F3-557A-48f6-A36C-B999B2BB6BE7")]    [ComponentCategory(CategoryTypes.CATID_Encoder)]

public class ContentTypeEditingComponent : Microsoft.BizTalk.Component.Interop.IComponent, IBaseComponent, IPersistPropertyBag, IComponentUI

{

  private string contentType;

  private static readonly string CONTENTTYPE_NAME = "ContentType";


        #region IComponent Members

        public Microsoft.BizTalk.Message.Interop.IBaseMessage Execute(IPipelineContext pContext, Microsoft.BizTalk.Message.Interop.IBaseMessage pInMsg)
        {
            if (pInMsg != null)
            {
                if (pInMsg.BodyPart != null)
                {
                    // If the Content type is not set, then default to text/html
                    pInMsg.BodyPart.ContentType = "text/html";
                }
            }

            return pInMsg;
        }

        #endregion
}
Compile the assembly of this pipeline component, create a new Send pipeline in Visual Studio.NET, add your pipeline component assembly in the toolbox of the pipeline designer and deploy your pipeline in BizTalk. This should do the trick and you would be sending email messages as content type "text/html" :)

Thursday, October 21, 2010

Finding the modified date of your tables, views and stored procedures in SQL Server 2005

Working on the next version of a product that uses a back-end database requires you to track all the modifications done on the tables, views and stored procedures.

A quick way to find the modified dates of your tables, views, stored procedures in SQL Server is:

For stored procedures:

select [name], create_date, modify_date from sys.procedures
order by modify_date desc

For tables:

select [name], modify_date from sys.tables
order by modify_date desc

For views:
select [name], modify_date from sys.views
order by modify_date desc

Using these scripts, you can get the list of the recently added / modified tables. Tracking your team's activities on your database will help you create the final deployment SQL script.


Thursday, March 18, 2010

Debugging localhost traffic in Fiddler


Fiddler is  a great tool to web-debug your HTTP traffic. It acts as proxy between your computer and the Internet. However, by default it does not capture any localhost to localhost HTTP traffic.

I searched on the net regarding this and most of the articles and blogs that I found recommended using a dot “.” (period) after the localhost in your URLs for e.g. use http://localhost.:5282 instead of http://localhost:5282

I tried it but it did not work. The Fiddler’s proxy gave an error for being unable to process this URL. After a couple of more searching I found out that I am supposed to use this URL: http://ipv4.fiddler:5282/ and it worked just fine. J

Happy fiddling.

Tuesday, March 16, 2010

Disabling WCF security


I recently faced an issue from one of our vendors trying to access our web services with their Java clients. They were able to download the WSDL file but got some security errors when calling our web methods. I had tested my web services with my own test clients developed in .NET and they seemed to be working absolutely fine. I decided to investigate this issue and here is what I found:

Whenever you create a new Windows Communication Foundation (WCF) service in Visual Studio.NET 2008, it automatically creates service entries in your application’s configuration file with the default end point binding of wsHttpBinding. I created my sample CustomerService as a WCF service:

<service behaviorConfiguration="WebServiceApp.CustomerServiceBehavior"
    name="WebServiceApp.CustomerService">
    <endpoint address="" binding="wsHttpBinding" contract="WebServiceApp.ICustomerService">
     <identity>
      <dns value="localhost" />
     </identity>
    </endpoint>
   <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>

As you can see the end point binding done is of WSHttpBinding. It uses HTTP transport and by default provides message security along with support for transactions, reliable messaging and WS-Addressing. However the issue is that the default Security mode for WSHttpBinding is Message. The WSHttpSecurity.Message property has its own default behavior of:
I ran Fiddler tool to observe the message exchanges between my .NET test clients and WCF web services. It turned out that the test clients had to call my web service three times (negotiating service credentials, passing the encrypted data and security tokens).

Hence for a proper web service calling to take place the Java clients then should implement this functionality of Message security as required by the WSHttpBinding. After discussions with the vendor it was decided that since the communication takes place over a secure network and the web services being called are not exchanging user credentials (passwords or credit card numbers), I might as well remove the Message security from my web services.

Here is how you can remove disable security:

Removing Message Security by using BasicHttpBinding

Use BasicHttpBinding as the binding for your web service:

<service behaviorConfiguration="WebServiceApp.CustomerServiceBehavior"
         name="WebServiceApp.CustomerService">
  <endpoint address="" binding="basicHttpBinding" contract="WebServiceApp.ICustomerService" />
</service>

For BasicHttpBinding, security is turned off by default.

Removing Message Security from WSHttpBinding

If you want to disable security but at the same time use the WS-Addressing features of WSHttpBinding create a binding entry under bindings->wsHttpBinding and specify Security mode a “None” in your config file:

<bindings>
   <wsHttpBinding>
      <binding name="NoSecurityBinding">
         <security mode="None">
            <transport clientCredentialType="None" />
            <message establishSecurityContext="false" />
         </security>
      </binding>
   </wsHttpBinding>
</bindings>

Then tell your service to use this binding in bindingConfiguration of the end point:

<service behaviorConfiguration="WebServiceApp.CustomerServiceBehavior"
         name="WebServiceApp.CustomerService">
  <endpoint address="" binding="wsHttpBinding" bindingConfiguration="NoSecurityBinding"
            contract="WebServiceApp.ICustomerService" />
</service>


Sunday, March 14, 2010

Test your SOA web services using SOAP UI tool


The SOAP UI tool is a great tool that helps you to quickly test your web services. It is an easy to use tool that makes your SOA testing fun and easy.

I recently had the opportunity to use it on one of my SOA projects and it helped me a lot in debugging my web services. I had published some web services that I had developed in .NET 3.5 using Windows Communication Foundation (WCF) and this vendor company acted as the client consuming those web services. The vendor was developing his client on J2EE technology, possibly JSP/servlets web site.

During testing, the vendor told me that my web services were throwing exceptions containing messages that I had wrapped in a fault contract. The vendor’s development team just sent me the SOAP message that was causing my web service to throw an exception. Here is how I used the SOAP message as an input in the SOAP UI tool  to call my web service method:

Create SOAP UI Project:

Launch your soapUI tool. Right click on the Projects option in the left pane. Select the option of New soapUI Project.


Figure 1

Enter WSDL path:
The new soapUI project menu asks you to enter the name of the project and the WSDL path of your web service. Let’s assume that we will call one of my test web services of ProductsService and will call the web method of CreateProduct. I have published my WSDL at http://localhost:50911/ProductsService.svc?wsdl. I have specified this in Figure 2:


Figure 2

By selecting the check box for Create sample requests for all operations, the tool will automatically generate a sample request SOAP message. Click on OK. The tool generates a sample web request as shown in Figure 3:


Figure 3

Specify the SOAP message:

Double click on Request 1 and you will be able to see the sample request created. I will copy-paste the SOAP message on the Request 1 pane, sent to me from the vendor’s development team:


Figure 4

Note in figure 4 that I have highlighted the node in the SOAP message. The specifies the fully qualified namespace of my service contract of IProductsService’s web method of CreateProduct. The most important thing to note is . Here you will specify the URL path of the test web service where you have hosted. Since I need to debug the web service, I have launched it through Visual Studio.NET:  http://localhost:50911/ProductsService.svc

(I have also added xmlns:wsa="http://www.w3.org/2005/08/addressing" as an attribute of , because apparently soapUI tool does not add this by default).

Here is the SOAP request message:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"
                   xmlns:web="http://WebServiceApp.ServiceContracts/"
               xmlns:wsa="http://www.w3.org/2005/08/addressing">
  <soap:Header>
    <wsa:MessageID>urn:uuid:2161b61d-fe07-4cdb-a125-7b221100608awsa:MessageID>
    <wsa:ReplyTo>
    wsa:ReplyTo>
  soap:Header>
  <soap:Body>
    <web:CreateProduct>
      <web:productName>ABCweb:productName>
      <web:productDescription>XYZweb:productDescription>
      <web:productCode>5001web:productCode>
      <web:company>ABCXYZweb:company>
    web:CreateProduct>
  soap:Body>
soap:Envelope>

Call the web service:

Call the web service by pressing on the green play button. As you can see below the web service returns the following fault exception response wrapped in a fault contract:

  <s:Header>
    <a:RelatesTo>urn:uuid:2161b61d-fe07-4cdb-a125-7b221100608aa:RelatesTo>
  s:Header>
  <s:Body>
    <s:Fault>
      <s:Code>
        <s:Value>s:Senders:Value>
      s:Code>
      <s:Reason>
        <s:Text xml:lang="en-US">Product code should be in the range of 1 to 500s:Text>
      s:Reason>
      <s:Detail>
        <DefaultFaultContract xmlns="http://WebServiceApp.FaultContracts/2008/02" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"/>
      s:Detail>
    s:Fault>
  s:Body>
s:Envelope>

The vendor has specified the wrong product code. The web service expects the product code to be in the range 1 to 500. After the correcting the SOAP request message I specify product code 400 and consequently get the following successful response message:

  <s:Header>
    <a:RelatesTo>urn:uuid:2161b61d-fe07-4cdb-a125-7b221100608aa:RelatesTo>
  s:Header>
  <s:Body>
    <CreateProductResponse xmlns="http://WebServiceApp.ServiceContracts/">
      <CreateProductResult>25CreateProductResult>
    CreateProductResponse>
  s:Body>
s:Envelope>

Although this example is quite trivial but in case if you have large SOAP request messages having a lot of data fields, then the soapUI tool comes quite handy.