Develop an ASP.NET API site together with an Angular JS frontend

Recently I’ve started to play around with Angular JS and ASP.NET core. I’ve created an ASP.NET web API project and (basically) copied the Angular frontend to wwwroot.

All Angular stuff is running by using an index.html file containing the app and all pages are displayed by using an MVC like scheme (aka http://www.example.com/customer/list). API calls to the backend services are encapsulated within the path /api (e.g. http://www.example.com/api/customer).

After creating a web API project with Visual Studio, it’s not possible to drive static files which are copied to wwwroot. Therefore two more lines are necessary to drive files from within an API app. Please add the following lines before the app.UseMvc() call in Startup.cs:

...
// switch to index.html on any request not starting with "api/"
// (C# controller) nor being an existing static file
app.Use(async (context, next) =>
  {
    await next();
    var path = context.Request.Path.Value;
    var fileInfo = env.WebRootFileProvider.GetFileInfo(path);
    if (!path.StartsWith("/api", StringComparison.InvariantCulture)
        && !fileInfo.Exists)
    {
      context.Request.Path = "/index.html";
      await next();
    }
  });
app.UseDefaultFiles();
app.UseStaticFiles();
app.UseMvc();
...

The first statement (app.Use(...); ) will handle all not known requests to the backend and route them to index.html (e.g. the angular router will handle the request).

Any request that is not routed via api  and that does not map to an existing file under wwwroot  will be forwarded to index.html. Routing errors (e.g. invalid pages, …) are forwarded to /404 .

app.UseDefaultFiles() will check for default files if a root path or directory is given. In the current scenario this will work only for the root directory which is sufficient.

app.UseStaticFiles() is responsible to serve all files located under

Example code can be found at https://github.com/steven-r/angular-cli-webapp-api.

Using datatables.net with ASP.NET webforms – A generic approach

datatables.net is a flexible HTML table component used in many applications. Recently (in a large ASP.NET webforms legacy application) we’ve had the need to switch from a commercial product towards a product which is easier to maintain and which does not contain 5000 features where we use only 10 out of them (and some of the others are creating problems).

Using datatables.net is very easy and requires only limited knowledge on JavaScript in case you are providing table data together with the data to be displayed. You can find tons of examples on the datatables.net home page.

In case you are going to display data which is

  • hard to generate on the fly (volume, complex queries) or

  • is changing during paging or other table operations

you need to load data from the server even after the page has been requested. The term used in datables.net is “server side processing”.

By using a .NET handler class and a generic interface that encapsulates the data provider we’ve generated a solution which can be easily adapted to create a generic data table provider implementation in ASP.NET web pages.

I’ve created a short demo on github that shows the general approach and might help as a base to use an own implementation.

Reading streamed data from Excel or CSV

Recently I stumbled over the task to read either CSV or Excel files and transfer data in an independent format to a server.

The existing software part implemented to similar approaches to

1. Read the file

2. Transfer the file into an intermediate format (a DataTable)

3. Transfer the file up to the server

The server took the file, read all data, translate number according to a given number format sent by the client, …

Reviewing the code resulted into a couple of drawbacks: redundant code, performance, use of language depending information on the server side, etc.

As a result I looked for an approach to

1. combine CSV and excel load within one flow and

2. have data translated on the client side into a format which can be read by the server without knowledge of the client user language (or the date format used for loading files)

Based on a code example for IDataReader (http://blogs.msdn.com/b/anthonybloesch/archive/2013/01/23/bulk-loading-data-with-idatareader-and-sqlbulkcopy.aspx) I had the idea to create a library which streams data independent of the input format.
Continue reading “Reading streamed data from Excel or CSV”

I18n: Parsing Decimal values

At Tideum and for TimeJack we are developing line of business applications which usually handle numbers. As we are developing our software for international markets we usually face the problem of users entering numbers in a format that is not the same as the current locale (e.g. Germans are entering numbers in English locale and vice versa). This happens very often if data is copied from 3rd party applications (e.g. SAP or Excel).

Parsing those numbers with the standard .NET functions (aka. Decimal.Parse()) is parsing only a fixed language, e.g.

string source = "123,45";
decimal value = Decimal.Parse(source);

depends on the current thread culture settings. In case the current settings are “de-DE” (or “de-AT”), the conversion will return value == 123.45, for “en-US” value == 12345 will be returned and for “de-CH”/”fr-CH” a System.FormatException is thrown.
Continue reading “I18n: Parsing Decimal values”

WiX 3.5 released

I’d like to highlight the fact that WiX has been as released as version 3.5 stable. The official release can be downloaded here. The announcement is here.

We’re using WiX at Tideum now for about two years for all products which need an installer (internally and externally).

Best wishes to the team from one of your fans :-).

Creating bootstrapper installers with dotNetInstaller

Currently we are using WIX integrated into our TFS build process to create our installation packages. This has been proved to be a fast and cheap way to create professional setup packages.Actually there was the need to create combined setup packages consisting of several MSI packages generated by WIX.After looking at several packages (including WIX 3.6 burn, and others) we decided to start over with dotNetInstaller. Using a XML file you are able to generate .EXE bootstrappers. After playing around with this tool we decided to incorporate this directly into our build process which wasn’t that easy as the integration needed to support the following “features”:

  • MSBuild (the integration is done in the .wixproj file)
  • Support for dynamic filenames (including the automatically generated version number)
  • Support for multiple languages

The following sections describe the steps to include this into our software: Continue reading “Creating bootstrapper installers with dotNetInstaller”

Register (D)COM executables with WIX

One of our projects is using a 3rd party library for licence protection (Licence Protector) which is based on C/C++ and therefore not available as a processor independant library (like managed c# DLLs).

During migration to 64 bit we had to switch from a 32 bit DLL to a DCOM server which serves 32 and 64 bit.

The DCOM server installs itself by starting the (server) executable with the parameter /regserver (and /unregserver for deinstallation).

There’re several ways installing (D)COM servers with WIX, but every method has it’s drawbacks. So we decided to use the (from our point of view) simpliest way by simply calling the executable during installation with the correct parameters.

The corresponding <component> element looks like this:

<Component Id="cmpLicence64Bit" Guid="GUID">
  <Condition>
    <![CDATA[LICPROT31THERE="unset"]]>
  </Condition>
  <File Id="filLicPro31Exe"
       Source="ExternalFiles\LicProtector310.exe"
       KeyPath="yes"/>
</Component>

The (de)registration will by done by calling the executable with two custom actions:

<CustomAction Id="caRegisterEXE"
             ExeCommand="
             FileKey="filLicPro31Exe"
             Return="check"
             Execute="commit" />
<CustomAction Id="caUnregisterEXE"
             ExeCommand="/unregserver"
             FileKey="filLicPro31Exe"
             Return="check"/>

The importand point is the order. The deregistration needs to be done before the actual file has been deleted already and the registration can only be done during “commit” phase after the correspoding executable has been installed successfully.

In addition the custom action should be executed only on installation or deinstallation of the corresponding component:

<InstallExecuteSequence>
  <!-- ... -->
  <Custom Action="caRegisterEXE"
    Before="StartServices">$cmpLicence64Bit > 2</Custom>
  <Custom Action="caUnregisterEXE"
    Before="UnregisterComPlus">$cmpLicence64Bit = 2</Custom>
  <!-- ... -->
</InstallExecuteSequence>

Creating NetworkService services with wix

One of our products had the need to create a windows service running as “NetworkService” user.

So we did it the simple way and created the following (wrong) script:

<Component Id="cmpVipeService" Guid="PUT-GUID-HERE">
  <!-- CreateFolder is necessary for components without files -->
  <File Id="filServiceExecutable" Source="$(var.VipeService.TargetPath)" KeyPath="yes"/>
  <ServiceInstall Id="srvVipeService" Name="VIPE [INSTANCE_NUMBER] Service" Start="auto" Type="ownProcess"
    ErrorControl="normal"
    Account='[WIX_ACCOUNT_NETWORKSERVICE]'>
  </ServiceInstall>
  <ServiceControl Id="StartsrvVipeService" Name="VIPE [INSTANCE_NUMBER] Service" Start="install" Wait="no" />
  <ServiceControl Id="StopsrvVipeService" Name="VIPE [INSTANCE_NUMBER] Service" Stop="both" Wait="yes" Remove="uninstall" />
</Component>

Testing on a local PC and a test server worked fine, as WIX_ACCOUNT_NETWORKSERVICE has been translated to “NT
AUTHORITY\NETWORK SERVICE” or “NT AUTORITÄT\NETZWERKDIENST” (in German) and the service has been installed successfully. The only difference between existing (NetworkService) users and our service has been the written username “NT AUTORITÄT\NETZWERKDIENST”.

Result: Test completed inside our domain.

Yesterday we started to deploy the software to the production environment on a dedicated internet server hosted externally (and therefore not included in our domain). And (as expected) we failed. The following error has been reported in the event log with the id NETLOGON – 3095 (Sorry, in German):

Dieser Computer ist als Mitglied einer Arbeitsgruppe konfiguriert, nicht als Mitglied einer Domäne. Der Anmeldedienst braucht bei dieser Konfiguration nicht gestartet zu sein.

In english: The computer is a member of a workgroup, not a domain. The NETLOGON service doesn’t need to be run.

As a result the installation failed.

On day with unsuccessful research I finally analized an existing 3rd party tool that installs a service with a NetworkService login as well. The solution was simply not to put WIX_ACCOUNT_NETWORKSERVICE but “NT AUTHORITY\NetworkService” for the Account parameter.

Windows MSI API translates this value automatically into the local representation (i.e. NetworkService or Netzwerkdienst, …). After changing the parameter and running the installation again the software package has been installed successfully.

Applying patches for transformed installations

With wix it’s possible to create transformation for products via the <InstanceTransforms> tag. We use this feature for one of our software products to install the same software with different versions on the same machine.

Recently we had the problem how to apply a patch that has been created as described in this post. After some research we are using now something like this (found here):

msiexec.exe /package {ProductCode} /update patch.msp

Creating Patches with wix

Updated 2011-05-16: For some reason the patch source file got corrupted. This has been fixed. Thanks Thomas.

One of our software projects require a setup system being used to deploy the software at the customer’s site. We started with several tools but stopped at wix as this tool seems to be a good compromise for tools like “InstallShield” and “Wise” (discontinued).

It integrates seamless into our build process except one thing and that’s patches.

Our idea was to create a release branch, declare one build as the “RTM” build and later on provide only patches which “enhance” the original build. I’ve started looking for information about patching with wix and found one valuable source here.

Starting from here, I’ve found that using this example with a real WIX-based setup (custom actions, transforms, …) doesn’t work.

Therefore I’ve changed the parameters and the flows…

Continue reading “Creating Patches with wix”