dotnetable

Experiences of working in software development with .NET.

Changing JSON properties to camel case notation

A quick note on how to change the JSON property names to camel notation. This is achieved by adding the following lines to the WebApiConfig class.

var settings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
settings.Formatting = Formatting.Indented;

This is how it would look in the class.

using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Web.Http;

namespace Carrera
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            var settings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
            settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            settings.Formatting = Formatting.Indented;

            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

Simple ASP.Net Gridview Sorting and Paging Example

The simplest way to perform paging and sorting in an ASP.Net webforms application is to use the SQLDatasource control. If you do not use the suite of DataSource controls paging and sorting can manually be achieved without too much extra work.

The page contains a GridView control that has paging and sorting enabled by setting AllowPaging and AllowSorting attributes to true. Height and width are optional.

<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True" Height="292px" 
OnDataBound="GridView1_DataBound" OnPageIndexChanging="GridView1_PageIndexChanging" OnSorting="GridView1_Sorting" 
Width="600px"></asp:GridView>

As I am not using any data access methods, I have created a private method to generate and return a DataTable of data.

private DataTable GetTableData()
{
	DataTable dt = new DataTable();
	dt.Columns.Add("ProductId", typeof(int));
	dt.Columns.Add("Name", typeof(string));
	dt.Columns.Add("ProductNumber", typeof(string));
	dt.Columns.Add("Quantity", typeof(int));
	dt.Columns.Add("UnitPrice", typeof(decimal));

	Random rnd = new Random();
	for (var i = 1; i <= 100; i++)
	{
		var qty = rnd.Next(1, 100);
		DataRow dr = dt.NewRow();
		dr["ProductId"] = i;
		dr["Name"] = $"Product{i}";
		dr["ProductNumber"] = $"A-{qty}";
		dr["Quantity"] = qty;
		dr["UnitPrice"] = i;
		dt.Rows.Add(dr);
	}
	return dt;
}

The webform has two properties that are used as accessors to values stored in viewstate, the name of the sort column and the sort direction.

public string SortColumn
{
	get {return Convert.ToString(ViewState["SortColumn"]);}
	set {ViewState["SortColumn"] = value;}
}

public string SortDirection
{
	get { return Convert.ToString(ViewState["SortDirection"]); }
	set { ViewState["SortDirection"] = value; }
}

In the page load method, if the page load was not from a postback the default sort direction and sort column is set and the BindGrid method is called.

protected void Page_Load(object sender, EventArgs e)
{
	if (!Page.IsPostBack)
	{
		SortDirection = "ASC";
		SortColumn = "ProductId";
		BindGrid();
	}
}

The Bind Grid method calls the GetTableData method to generate the data and the data is bound to the grid.

private void BindGrid()
{
	var dt = GetTableData();
	if (dt != null)
	{
		//Sort the data.
		dt.DefaultView.Sort = SortColumn + " " + SortDirection;
		GridView1.DataSource = dt;
		GridView1.DataBind();
	}
}

The PageIndexChanging event is raised when one of the pager options is clicked, but before the GridView handles the paging operation. Notice the BindGrid method is called causing the grid to be rebound to the data.

protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
	GridView1.PageIndex = e.NewPageIndex;
	BindGrid();
}

The Sorting event is raised when the column header link is clicked, but before the GridView control handles the sort operation. Here the sort expression, in this case the data column to sort by and the sort order are set. The data is then rebound by calling the BindGrid method.

		
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
	SortDirection = (SortDirection == "ASC") ? "DESC" : "ASC";
	SortColumn = e.SortExpression ;
	BindGrid();
}

The DataBound event fires when all the databinding for the GridView is finished. All we do here is find the index of the GridView column that matches the sort expression and add an image to the column header to indicate the current sort direction.

protected void GridView1_DataBound(object sender, EventArgs e)
{
	int columnIndex = 0;
	foreach (DataControlFieldHeaderCell headerCell in GridView1.HeaderRow.Cells)
	{
		if (headerCell.ContainingField.SortExpression == SortColumn)
		{
			columnIndex = GridView1.HeaderRow.Cells.GetCellIndex(headerCell);
			break;
		}
	}

	Image sortImage = new Image();
	sortImage.ImageUrl = string.Format("images/sort-{0}ending.png", SortDirection);
	GridView1.HeaderRow.Cells[columnIndex].Controls.Add(sortImage);
}

That is pretty much it.

Using HtmlHelpers to generate Custom TextArea (Part 2)

This is Part 2 in a (very) mini series on HtmlHelper methods. Here is the link for Part 1, Using HtmlHelpers to generate HTML elements

This article is about creating a HtmlHelper for a TextArea although the same principles apply for other input controls as well. For this example I have created a simple Employee model class.

namespace HtmlHelpersDemo.Models
{
    public class Employee
    {
        public string Title { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
}

Nothing special about the controller. An Employee object is instantiated and passed to the view. Following MVC conventions the Index view from the Home folder is rendered.

using HtmlHelpersDemo.Models;
using System.Web.Mvc;

namespace HtmlHelpersDemo.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View(new Employee());
        }
    }
}

Before looking at the new TextAreaFor HtmlHelper method we will look at how it is called. The method is written as an extension to the Mvc HtmlHelper class (System.Web.Mvc) which allows it to be called the same way the built in TextAreaFor methods are called using @Html..
The first example passes values in a htmlattributes parameter in the form of a class and a data_ref attribute which has an underscore rather than hyphen.

@model HtmlHelpersDemo.Models.Employee
@using HtmlHelpersDemo.Code;
@{
    ViewBag.Title = "Index";
}
<h2>Index</h2>

@Html.TextAreaFor(m => m.FirstName, new { @class = "input" , data_ref="123"}, false)

@Html.TextAreaFor(m => m.FirstName,  false)

Here is the code that does all the work. As mentioned this is written as a HtmlHelper extension method so the first parameter is not actually passed in from the calling code. Rather it defines the class the method is associated with and provides us with a local reference to manipulate, in this instance the local name of HtmlHelper is htmlHelper.

using System;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Routing;

namespace HtmlHelpersDemo.Code
{
    public static class TextAreaExtensions
    {
        public static MvcHtmlString TextAreaFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression, object htmlAttributes, bool IsReadonly)
        {
            var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
			attributes["class"] = "form-control" + " " + attributes["class"];

            if (IsReadonly)
            {
                attributes.Add("readonly", IsReadonly);
            }

            MvcHtmlString html = default(MvcHtmlString);
            RouteValueDictionary routeValues = new RouteValueDictionary(attributes);
            html = System.Web.Mvc.Html.TextAreaExtensions.TextAreaFor(htmlHelper, expression, routeValues);
			TextAreaFor()
            return html;
        }

        public static MvcHtmlString TextAreaFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression, bool IsReadonly)
        {
            return htmlHelper.TextAreaFor(expression, null, IsReadonly);
        }
    }
}

Lets disect what the method is doing. The first line calls a built in method passing in the htmlAttributes parameter. This method replaces underscore characters with hyphens which is how the data_ref is translated to data-ref when rendered.

var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

As all text area controls is this application requires the form-control css class, it is being added to the attributes in this method along with any other css class passed in throught the htmlattributes parameter.

attributes["class"] = "form-control" + 
    (!string.IsNullOrEmpty( attributes["class"] as string) ? " "+ attributes["class"] : "");

If the IsReadOnly parameter is set, the readonly state of the control is assigned to the attribues object.

if (IsReadonly)
{
	attributes.Add("readonly", IsReadonly);
}

The final four rows create a TextArea input control from the attributes and route values if there are any.

MvcHtmlString html = default(MvcHtmlString);
RouteValueDictionary routeValues = new RouteValueDictionary(attributes);
html = System.Web.Mvc.Html.TextAreaExtensions.TextAreaFor(htmlHelper, expression, routeValues);
return html;

There rendered html for the two examples above looks like this.

<textarea class="form-control input" cols="20" data-ref="123" id="FirstName" name="FirstName" rows="2">
</textarea>

<textarea class="form-control" cols="20" id="FirstName" name="FirstName" rows="2">
</textarea>

Using HtmlHelpers to generate HTML elements (Part 1)

When working in a Microsoft MVC application, creating forms containing form elements is made easier due to the number of available HtmlHelper methods for a TextBox, DropDownList, TextArea etc. Although HtmlHelpers are not only available for form controls, there are helpers for links, view rendering, validation and more built in to the MVC libraries.

At some point there will not be a HtmlHelper that does just what is needed and want to share a few examples of customer HtmlHelpers.

Example 1. Label Helper
This example generates html label page elements. Creating the label is as simple as building a string containing the html to be displayed on the page.

using System.Web.Mvc;

namespace HtmlHelpersDemo.Code
{
    public static class Helpers
    {
        public static MvcHtmlString Label(string labelText)
        {
            return new MvcHtmlString(string.Format("<label>{0}</label>", labelText));
        }

        public static MvcHtmlString Label(string labelText, string forAssociatdControl)
        {
            return new MvcHtmlString(string.Format("<label for='{0}'>{1}</label>", forAssociatdControl, labelText));
        }
    }
}

These methods return an instance of type MvcHtmlString class which represents an HTML-encoded string. MvcHtmlString is a member of System.Web.Mvc namespace (in System.Web.Mvc.dll).

Usage
To display a label we add a using statement at the beginning of our view.

@using HtmlHelpersDemo.Code;
@{
    ViewBag.Title = "Home Page";
}

@Helpers.Label("First Name:")

@Helpers.Label("Last Name:", "SomeControl")

When rendered the page contains the labels as expected.
html-helper-label-code

This is quite a simple example but the method could be applied to creating a html table row or even the whole table.

Date Formatting and Calling C# Script From XSLT in BizTalk 2013 Map

I needed to set a field value to a formatted date string in a map. As we are using BizTalk 2013R1 we are restricted to XSLT1.0 which makes date formatting more difficult (XSLT2.0 has better support for dates). However this got me thinking of the different ways this could be achieved. For demonstartion purposes lets say I have the below schema

biztalk-date-functoid
the last three fields are the fields of interest and are set up with the data types as in this table

Field Data Type
ApprovedOn xs:dateTime
CreatedDate xs:date
CreatedTime xs:time

Setting the ApprovedOn field to the current datetime value is quite straight forward with a C# scripting functoid.

biztalk-date-functoid-linked
Setting the CreatedDate and CreatedTime fields can be done in a similar way and just requires a C# scripting functoid for each field that returns the date in the relevant format.

The CreatedDate C# scripting functoid

public string CurrentDate()
{
    return DateTime.Now.ToString("dd-MM-yyyy");
}

The CreatedTime C# scripting functoid

public string CurrentTime()
{
    return DateTime.Now.ToString("HH:mm:ss");
}

This is the result of testing the map with a valid input file.

<Employee>
  <ForeName>Percy</ForeName> 
  <ApprovedOn>29/09/2016 11:59:43</ApprovedOn> 
  <CreatedDate>29-09-2016</CreatedDate> 
  <CreatedTime>11:59:43</CreatedTime> 
</Employee>

Moving on to the orignal problem I was trying to solve
The destination schema contains an element which itself contains three child elements

biztalk-employeeoutput-schema

defined with the following data types

Field Data Type
Date xs:date
Time xs:time
Type xs:string

In the real life scenario the Type field is calculated from a number of fields in the source schema. To keep this example focused I have hard coded the Type field using a String Concatenate functoid. The output of the Concatenate is an input parameter to a scripting functoid that builds the Action destination element using an Xslt template. The value for the Type field could have been hardcoded in the scripting functoid but linking this way demonstrates parameter handling in an Xslt template.

biztalk-map-complete

So here we have a scripting funcoid (with the exclamation warning) containing inline C# code that consists of a singel FormatCurrentDateTime method.  This method has a single string parameter which will format the returned string.

public string FormatCurrentDateTime(string format)
{
    return DateTime.Now.ToString(format);
}

BizTalk adds the C# script in a block at the bottom of the xslt when the map is compiled. This can be seen by compiling the assembly containing maps, and using the Show all Files command in Visual Studio Solution Explorer to look at the corresponding .btm.cs file to see what has been added.
There is also a scripting functoid containing an xsl template. This template accepts a single parameter for the Type element. There are also two variables initialised by calling the FormatCurrentDateTime method passing in a string defining the format of the DATETIME returned.  Note the use of userCSharp: prefix on the method call.

<xsl:template name="mapActionTemplate">
    <xsl:param name="type" />
    <xsl:variable name="date" select="userCSharp:FormatCurrentDateTime('yyyy-MM-dd')"/>
    <xsl:variable name="time" select="userCSharp:FormatCurrentDateTime('HH:mm:ss')"/>
        <xsl:element name="Action">
            <xsl:attribute name="Type">
                <xsl:value-of select="$type" />
            </xsl:attribute>
            <Date>
                <xsl:value-of select="$date" />
            </Date>
            <Time>
                <xsl:value-of select="$time" />
            </Time>
        </xsl:element>
</xsl:template>

For additional information on maps see this series of articles on Bizbert.

Credit to the original article:
Useful Cheat Code in Mapping (Calling C# code from XSLT) « BizTalk Server Tutorial

JavaScript Confirm on ASP.NET Form Submit

This is a quick demo showing how to prompt the user to confirm when submitting a form on an ASP.Net page.  We start with a simple form.

form

There is some server side code which will populate a label with the current date and time when the form is submitted.

protected void SubmitButton_Click(object sender, EventArgs e)
{
    Timestamp.Text = DateTime.Now.ToString();
}

If the user is simply required to confirm the submitting of the form then an OnClientClick action can be specified.

<asp:Button runat="server" ID="SubmitButton" Text="Submit" CssClass="btn btn-default" OnClientClick="return confirm('Do you want to submit this page?')" CausesValidation="false" OnClick="SubmitButton_Click" />

When the form is submitted it will display the confirmation prompt.
confirm

If the Cancel button is pressed the form will not be submitted. If the OK button is pressed the form will be submitted and the current date and time will be displayed in a label.

form-submitted

The form in this example very simple. In a real application forms are usually more complicated with fields that require validation. Suppose we only want to prompt the user to confirm the form submission if the form is validated. This is still simple to do with very minor changes, the trick is to check the status of the validation on the client side first by calling the Page_ClientValidate method.

<div class="form-group">
    <asp:Label runat="server" AssociatedControlID="Name" CssClass="col-md-2 control-label">Name</asp:Label>
<div class="col-md-10">
        <asp:TextBox runat="server" ID="Name" CssClass="form-control" />
        <asp:RequiredFieldValidator runat="server" ControlToValidate="Name" CssClass="text-danger" ErrorMessage="Name is required." />
    </div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
        <asp:Button runat="server" ID="SubmitButton" Text="Submit" CssClass="btn btn-default" OnClientClick="if (Page_ClientValidate()){return confirm('Do you want to submit this page?')}" CausesValidation="false" OnClick="SubmitButton_Click" />
    </div>
</div>

With this code the form is not valid until the Name textbox contains a value. Only when all the validation controls are valid will the Confirm prompt be displayed. As before, if the Cancel button is pressed the form will not be submitted. If the OK button is pressed the form will be submitted and the current date and time will be displayed in a label.

Configuring SpecFlow and NUnit in Visual Studio 2015

How to set up Specflow and NUnit v3 in Visual Studio 2015. I have already added a new Class Library project named SpecFlowTest to an empty solution.


Step 1. Install SpecFlow extension for Visual Studio 2015

Once the SpecFlow extension is installed you will be able to add SpecFlow items to a project from the Installed Templates list of the Add Item dialog box.

  1. In the Tools menu select Extension and Updates…. This will open the Extensions Manager dialog.
  2. In the dialog choose the Online gallery in the left pane.
  3. In the right pane type specflow in the search box.
  4. In the middle pane find Specflow for Visual Studio 2015 in the results list and click the Download button. If you already have it installed a installed-tick tick will be displayed instead of a download button.

specflow-extension-vs2015

The package will be downloaded

specflow-extension-vs2015-download

A dialog will appear with a summary on the installation and prompting confirmation of the install

specflow-extension-vs2015-install

The installation will complete.

specflow-extension-vs2015-installing

Once installed a web page normally opens in Visual Studio with this address, http://www.specflow.org/guidance/first-steps. In some cases a restart of Visual Studio may be required.


Step 2. Installing NuGet packages

As usual NuGet packages can be installed via the window interface
Tools > NuGet Package Manager > Manage NuGet Packages for Solution…
or if you prefer, via the command line
Tools > NuGet Package Manager > Package Manager Console
There are a few ways to add the SpecFlow and NUnit libraries to a project,  either by installing individual packages for each product or by using combined packages.

Option 1. Combined Package

Open NuGet Package Manager and locate the SpecFlow.NUnit package.  This option will install both the SpecFlow and NUnit libraries as well as the NUnit runners for running the tests from TestExplorer in Visual Studio.  In the package description it does say NUnit version 2.6+ will be installed, at the time of this post NUnit version 3.0.0 was installed. In the future this may be a newer version of NUnit.
nuget-vs2015-specflow-nunit
And to install via command…

Install-Package SpecFlow.NUnit

Although NUnit version 3.0.0 is installed it can be upgraded to the latest version.  At this time the current version is 3.4.1.

nuget-vs2015-nunit3-update

And the NUnit update via command
Update-Package NUnit

And with that everything should be good to go.


Option 2. Installing Individual Packages

The packages can be installed separately.  Doing so would allow you to install a different test runner or a different unit testing framework.  Whatever the reason, if that is the case then you can follow these steps.

Install SpecFlow
With NuGet Package Manager open search online for the SpecFlow package.

nuget-vs2015-specflow

And via command

Install-Package SpecFlow

Install NUnit

This will install version is 3.4.1, no need for update.
nuget-vs2015-nunit3-install

And via command

Install-Package NUnit

Install NUnit3TestAdapter

Here I am installing a different test runner to the one installed in the combined package.  The result is the same, tests can be run from within Test Explorer.
nuget-vs2015-nunit3-testadapter

Install-Package NUnit3TestAdapter

If feature files have already been added to the project the below message will prompt for them to be re-generated.

specflow-change-detected

Conclusion

It seems logical to use the SpecFlow.NUnit combined package if NUnit is the unit test framework of choice.  If you will be using MSTest or a different test runner installing separate packages is not that much more work.

Biztalk Recipe – Content Based Routing Example

This post is more about the technique rather than the scenario, so the solution is somewhat over engineered for what the scenario requires.
I generally create a separate Biztalk Server Project for Maps, Schemas, Orchestrations and Pipelines. Each project may then contain folders to group related content.

Environment:
Windows Server 2008 R2 Enterprise
Biztalk 2013 R1
Visual Studio 2012
MSSQL Server 2008 R2

Example Scenario
The HR department has moved the employee records to a new all singing all dancing record system as part of the HR phase 1 project.  The payroll system is still in the legacy system and is being integrated with the new HR system in phase 2.  Until then data relating to new employees must be exported from the new HR system and imported into the legacy payroll system.  For this to work efficiently an automated process is preferred.  So far the new HR system is configured to automatically create a file containing basic employee details each time a new employee is created.
Biztalk will form part of the process by moving the employee files to a specific folder, which folder the file is moved to will be controlled by a value contained in the XML file itself (Content Based Routing).

The XML file in this example is very simple. The value of the Department will determine which folder Biztalk routes the file to.
For the purpose of this example there are two files, one called Employee_HR.xml

<Employee>
    <ForeName>Percy</ForeName>
    <Surname>Philips</Surname>
    <DOB>1980-12-05</DOB>
    <Department>HR</Department>
</Employee>

and one called Employee_IT.xml

<Employee>
	<ForeName>John</ForeName>
	<Surname>Jones</Surname>
	<DOB>1980-12-05</DOB>
	<Department>IT</Department>
</Employee>

The new HR system places the files in the location E:\Test\Input\EmployeeDefinitions.
If you are following along copy the two XML definitions above in to files and save them on your computer so you can locate them later.

The requirements state that (we will look at this in greater detail later)

  • If the employee department is HR the file should be placed in the E:\Test\Output\Employee_HR folder.
  • If the employee department is IT the fiel should be placed in the E:\Test\Output\Employee_IT folder.

Solution Part 1 – Visual Studio
The first we need is the schema of the Employee Definition XML file.

  1. Open Visual Studio and open/create a project to hold the schemas we will be creating.
    If a new project was created for this example make sure the the Application Name on the Deployment tab of the project properties is set.
  2. Right-click the project in Solution Explorer and select Add then Add Generated Items… (If you prefer to use the main menu, on the Project menu, click Add Generated Items…)
  3. In the Add Generated Items dialog box, click Generate Schemas in the Templates section then click the Add button.
  4. In the Generate Schemas dialog select Well-Formed XML for the Document Type and for the Input File browse to and select one of the employee definition files you saved earlier.  It does not matter which file as both have the same schema.If you see Well-Formed XML (Not Loaded) in the drop-down list, Microsoft suggests you continue and select the appropriate document type anyway, and you will be guided through the process of installing the missing DLL. Then repeat these steps.

    For additional help see the post on Biztalk-Installing Schema Editor Extensions
  5. Click OK once a file is selected.

If the schema generated successfully there will now be a schema file with a name similar to the file selected (different extension .xsd).

biztalk-imported-employee-schema

For parts of Biztalk to be able to read the value of the Department we need to set the department as a promoted property.

  1. Expand the Schema tree so the full schema is visible.
  2. Right-click the Department and in the context menu select Promote then Quick Promotion. Biztalk will inform that a new file is being added to the project and that the Employee schema has changed.
  3. You should see a new schema named something like PropertySchema.xsd.

biztalk-promoted-department-property
As Visual Studio has created the schema file it will contain the property that was just promoted and may even contain an default Property1 property which can be deleted. This is all we need to do in Visual Studio. The project can now be built and deployed.

Solution Part 2 – Biztalk Server Administration Console
Looking back at the rules specifed above Biztalk needs to be able to receive a file from a location, process the file and save the file to a location.

Receiving a file from a location – Set up a Receive Port/Location

  1. Open Biztalk Server Administration
  2. Expand the console tree through the following nodes until you can see the application you want to create a receive port. In my case this is the Learning application.
    • BizTalk Server Administration
    • BizTalk Group
    • Applications
  3. Right-click Receive Ports, point to New, and then click One-way Receive Port.
  4. Give the receive port a Name.
    biztalk-receive-port
  5. In the left pane, click Receive Locations
  6. In the Receive Locations panel click New
  7. In the Receive Location Properties window specify a Name of the Receive location.
  8. Select XMLReceive from the Receive pipeline drop down.
    biztalk-receive-location
  9. In the Transport group, select FILE from the Type drop down and click Configure
  10. In the FILE Transport Properties dialog, on the General tab,  browse to the folder where the file will be picked up from.  In this scenario it is the folder the new HR system is configured to automatically create a file containing basic employee details each time a new employee is created.
    biztalk-receive-location-configure
  11. Click OK on each dialog to return to the Receive Ports list.

Sending a file to a location – Set up a Send Port

Setting up a Send port is very much like setting up a Receive Location.  First we set up where BizTalk will place the files for employees in the HR department.  For HR employees the folder will be E:\Test\Output\HR and for IT employees it will be E:\Test\Output\IT.  For you these location will probably be different.

  1. Right-click Send Ports, point to New, and then click Static One-way Send Port.
    biztalk-send port-hr
  2. In the Transport group, select FILE from the Type drop down and click Configure to open  the FILE Transport Properties dialog.
  3. In the FILE Transport Properties dialog, on the General tab,  browse to the Destination folder where the files for HR department will be placed, in my case E:\Test\Output\HR.
  4. Click OK.
  5. Select Filters on the left navigation.
  6. Create 2 filters
    biztalk-send-port-hr-filters

    • Property: BTS.ReceivePortName
      Operator: ==
      Value: ReceiveEmployeeDefinition
    • Property: Learning.Schemas.Employees.Department
      Operator: ==
      Value: HR
  7. Click OK.

To set up where BizTalk will place the files for employees in the IT department repeat the above steps.  I set the Destination folder on the FILE Transport Properties dialog to be E:\Test\Output\IT.  I set the filters for picking up the IT files as

  • Property: BTS.ReceivePortName
    Operator: ==
    Value: ReceiveEmployeeDefinition
  • Property: Learning.Schemas.Employees.Department
    Operator: ==
    Value: IT

That should be it.  Ensure the Receive Locations are Enabled and the Send Ports are started.

When a file is created in EmpoyeeDefinitions folder by the HR system Biztalk should pick it up and place a copy in either the HR or IT folder depending on the value of the department.

Things To Note
Are you familiar with the saying “There’s more than one way to skin a cat”, gross I know. Putting cats to one side there is certainly more than one way to create a schema or a promoted property.

A DOS Command To Map A Network Drive

Just a quick post with DOS commands to map a network drive connecting as a specific user and logging the results.

echo Start %date% %time% >> D:\logs\drivemap.txt
net use z: /delete /yes >> D:\logs\drivemap.txt
echo Mid %time% >> D:\logs\drivemap.txt
net use z: \\10.10.10.10\INVOICEFILES /user:USERNAME PASSWORD /persistent:yes >> D:\logs\drivemap.txt
dir z: >> D:\logs\drivemap.txt
echo End %time% >> D:\logs\drivemap.txt

This is something we did for a project a while back and want to keep a note for future.

Biztalk – Installing Schema Editor Extensions

Environment:
Windows Server 2008 R2 Enterprise
Biztalk 2013 R1
Visual Studio 2012
MSSQL Server 2008 R2

The steps to create a schema from an existing XML file are

  1. In Solution Explorer, right-click a BizTalk project, point to Add, and then click Add Generated Items…
  2. In the Add Generated Items dialog box, in the Templates section, click Generate Schemas, and then click Add.
  3. In the Generate Schemas dialog box, in the Document type drop-down list, select Well-Formed XML.
  4. Browse to select an Input file and click OK

When following the above steps the Document type drop down on the Generate Schemas dialog may display ‘Well-Formed XML (Not loaded)’.
biztalk-generate-schemas-dialog
A message similar to below will be displayed (the path will be different depending on the version of Biztalk installed)
biztalk-schema-generator
When running the InstallWFX.vbs file (or InstallDTD.vbs file) a dos prompt may flash up and although it appears to have worked the same message will be displayed as before.
In fact from my own experience, in the past I have tried different combinations of

  • Running the file by double-clicking from Windows Explorer.
  • Running the file as administrator from Windows Explorer.
  • Opening a Command Prompt and running the file.
  • Opening a Command Prompt as administrator and running the file.
  • Opening a Developer Command Prompt for VS2012 and running the file.
  • Opening a Developer Command Prompt for VS2012 as administrator and running the file.
  • Restarting Visual Studio after each attempt.

Hopefully one of these options work, if not then some people have reported to solve the situation by manually coying the Microsoft.BizTalk.WFXToXSDGenerator.dll and/or Microsoft.BizTalk.DTDToXSDGenerator.dll files to the extensions folder. i.e.
from
C:\Program Files (x86)\Microsoft BizTalk Server 2013\SDK\Utilities\Schema Generator
to
C:\Program Files (x86)\Microsoft BizTalk Server 2013\Developer Tools\Schema Editor Extensions
again, paths may differ depending on the version of Biztalk installed.

If copying the files works for you it may be worth taking this approach first every time.

BizTalk musings

Issues, patterns and useful tips for BizTalk development

Sandro Pereira BizTalk Blog

My notes about BizTalk Server 2004, 2006, 2006 R2, 2009, 2010, 2013 and now also Windows Azure BizTalk Services.

Exercises in .NET with Andras Nemes

Tips and tricks in C# .NET

WordPress.com

WordPress.com is the best place for your personal blog or business site.

%d bloggers like this: