Archive for the ‘.NET’ Category

NuGet packaging

I’m working with a consulting firm where there are some commons dll used in the projects , developed from other team members.
Adding the references to a dll by hand in the References folder is ok, but if there is a new version and you try to delete the dll from the References this operation typically causes a Visual Studio crash: the best approach is to delete the reference, with the projects closed, into the .csproj file: then reopening the solution no problems to add the new version.
So after years of NuGet as a customer it was time to become an author.
So I created a dll: in this case, a localization support via XML files because the application was using translation tables from a SQL table and the SQL access was slowing down dramatically the customers.
In the same solution i added a standard MVC app for testing.
In order to make the host application working with this NuGet package are requested:
– a Localization folder with some initial sample XML files
– a new Controller, LocalesController, that essentially changes the value of a Cookie
– a change in Views\Web.Config
For the first two points , we must see something as

That is there is a completely new Localization folder, a new LocalesController in Controllers folder.
Without the new NuGet package we see

First thing, we need the NuGet executable, we can download it from here.
I’m using version 4.5.1.
Then you must generate a .nuspec file.
This can be generated by hand, but we can use the command

nuget spec

launched in the solution directory.
The .nuspec file is an xml structure, with the nodes that can be compiled by hand or using some default placeholders substituted form the values of the project properties, see this reference where is critical to understand the paragraph “Package folder structure”.
References about here, and here.
A Controller can be dynamically created but you know that is better if placed in the same namespace, and this can still be achieved via special placeholders, see also this.
I ended with this .nuspec file :

<?xml version="1.0"?>
<package >
        <description>MVC project Localization via XML fields.</description>
        <releaseNotes>First version.</releaseNotes>
        <copyright>Copyright 2018</copyright>
        <tags>mvc http xml localization</tags>         
        <file src="..\Acme.MvcLocalization\Localization\**\*.*" target="" />
        <file src="content\any\any\Controllers\LocalesControllers.cs.pp" target="content\Controllers" />
        <file src="content\any\any\Views\web.config.transform" target="content\Views" />

The first “any” is a code language, the second the target framework (see references).
In this case some parts are taken form projects, others by hand; it works on a structure like this:

the blurred parts corresponds to the “Acme” in .nuspec (for privacy i don’t reveal the consulting firm true name)
There is a part (Localization folders with the contained xml files) that must be copied “as is” in the Localization folder of the hosting project, this is done with

<file src="..\Acme.MvcLocalization\Localization\**\*.*" target="" />

Then in the controllers there is a .cs file followed from a .pp, this instructs NuGet to evaluate the file, in this case our .pp contains

using Acme.MvcLocalization;
using System.Web.Mvc;

namespace $rootnamespace$.Controllers
    public class LocalesController : Controller
        public ActionResult Index(string lang = "it_IT")
            Response.Cookies["AcmeCacheLang"].Value = lang;
			// cookie above fundamental
            if (Request.UrlReferrer != null)
			var message = Localization.Get("changedlng");
			return Content(message);

Note the $rootnamespace$ : when the package is installed it is evaluated to the root namespace of the host application.
Now we examine web.config.transform

<?xml version="1.0" encoding="utf-8"?>

    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
        <add namespace="Acme.MvcLocalization" />
        <add namespace="Acme.MvcLocalization.Helpers" />

If we open the default Views/Web.Config of the Host application we can read

<?xml version="1.0" encoding="utf-8"?>

    <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
      <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />

    <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
        <add namespace="System.Web.Mvc" />
        <add namespace="System.Web.Mvc.Ajax" />
        <add namespace="System.Web.Mvc.Html" />
        <add namespace="System.Web.Optimization" />
        <add namespace="System.Web.Routing" />
        <add namespace="WebApplication1" />

It is intuitive to understand that at run time the 2 new namespaces in the .transform will be added to the node with the same path:


WebApplication1 is the name of the MVC host application that used for test.
Ok, now at a Command prompt in the NuGet project root (where there is the .nuspec file) we can generate the package

nuget pack Acme.MvcLocalization.csproj

So in the folder we have now a .nupkg files.
Obvious, every new release should be done after increasing the version in the project properties.
Now it time to test our new package.
First, while testing is not requested to publish it on the official NuGet repository but you can specify a folder on your pc a NuGet source: open the NuGet Package Manager and goto to Package Sources where to define a local path:

Done this, you can see available the new package:

Installing it , you can see that is created the new folder Localization with the xml files inside, in Controllers there is the LocalsController.cs with the changed namespace:

And in Views the web.config is changed:

The interesting fact is if you place a breakpoint in the NuGet project, it works:

Categories: .NET, Vs2015

Testing with Selenium grid

Selenium Server is basically a way for remote-execute our tests in Visual Studio.
This is a .jar Java executable, so it is needed the Java runtime as first thing; then we can download the Standalone Server in this page.
The Selenium “grid” is a technology that allows us to take a test and run it on a number of different machines that are part of this “grid”, that is a network of physical, cloud , virtual (Hyper-V or VmWare) or also Docker instances running the same or different operative systems.
You can create for example a grid with 3 different instances: a physical Mac, a Ubuntu virtual machine, a Windows 10 virtual machine.
One of the instances in the grid must be the main Hub, the others are Nodes that must be connected to the Hub.
In every node of the grid must be installed Java, because the .jar executable of the Selenium Server must be run locally on all nodes with different runtime parameters.
In order to run the .jar the Java executable must be reached from the system path.
The code for a grid test is different from the one for a “normal” test.
For example we can create a ConsoleApplication with Visual Studio (here I’m using Visual Studio 2015 Community, but every version since 2013 should work without problems), add 2 NuGet packages:
– Selenium.Support
– Selenium.WebDriver
The first is the only one that we need for a normal test, WebDriver is requested in order to do grid testing.
Done this , in the Main of our Program.cs we can write

using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;

 namespace WebDriverDemo
    class Program
        static void Main(string[] args)
            IWebDriver driver = new FirefoxDriver();
            driver.Url = "";
            var searchBox = driver.FindElement(By.Id("lst-ib"));
            searchBox.SendKeys("Donald Trump");

But if you launch this code, you get an error:

This happens because with Selenium is requested a driver for each browser that we intend to use for testing.
For Firefox is requested a Gecko driver that you can download from here.
For Windows systems we download an exe that must be placed in the same directory where we will plan to run the .jar of the Selenium Server, and in every case in a folder in the system path: i use a copy in c:\windows of the exe and another in the folder where is the .jar, but is my questionable practice.
And for the other browsers? For Chrome you can find the ChromeDriver here (the current latest version 2.35 here for Windows, Mac, Linux); the WebDriver for Edge from here; you can see the available downloads in the official Selenium downloads ( ).

After placed the exe, launching this code it is opened a command window:

And then is opened the browser, which opens the Google site and in the search textbox is written from the C# code our search term:

We used the Firefox driver and so, obvious, Firefox must be installed on the local machine.
There are drivers for Internet Explorer, Edge, Chrome…, also Opera.
If for example you are testing using Opera, Opera must be installed on the pc where you are launching the test, you must download the WebDriver for Opera, it is requested

using OpenQA.Selenium.Opera;

In the C# code and you must use OperaDriver() instead of FirefoxDriver().
If we want to use a remote browser for testing in a grid, it is needed to define the Hub that typically is the pc where you are developing.
On this pc (could be a virtual machine) in the folder where is placed the Selenium .jar file we must launch this .jar defining the pc as the hub.
Needless to say, every pc/vm/docker instance in the grid must be in the same network, it must be possible to ping the Nodes from the Hub.

For example I’m working with a vm which has the address, so I launched

java -jar selenium-server-standalone-3.8.1.jar -role hub -host

I specified the role as “hub”, and the -host parameter because i noticed that in a Hyper-V vm without specifying the -host parameter the server is waiting with another address 172* but cannot be reached from another vm.
The .jar is writing in the console some log, the last 2 rows are the most interesting:

16:46:27.227 INFO - Nodes should register to
16:46:27.227 INFO - Selenium Grid hub is up and running

We can read that we are advised how to connect a node to our hub, and it is used the port 4444.
It is also used 5555, so in my Windows 10 Hyper-V instance i configured the firewall in order to permit everything on these 2 port numbers, as Inbound and Outbound rules:

We would for example to make a test on a remote (another Hyper-V instance on the same host, in my case) Ubuntu 17.10 instance.

The browser with which you would make a test must be installed on the remote system, so if you want to make a Firefox test on a remote Ubuntu instance on this instance must be installed Firefox.
And must be installed the relative WebDriver in this remote instance; so in our case (test with Firefox) we must open on the remote Ubuntu a browser and go to , here click on “Clone or download” green button.
At this point we have downloaded a .tar.gz file (at the time of this post geckodriver-v0.19.1-linux64.tar.gz) in the Downloads folder, then we can made available on Ubuntu the driver with these commands:

tar -xvf geckodriver*

that extracts a file named geckodriver, then

chmod +x geckodriver
sudo mv geckodriver /usr/local/bin

Note that in my case the Ubuntu instance has IP (in Windows we use ipconfig, in Ubuntu ifconfig to see which is the local ip).

Done this , in a Unix shell i launched

java -jar selenium-server-standalone-3.8.1.jar -role node -hub -host


– the role now is “node” , not “hub”
– i used the http address given from the hub server for the connection to the hub (-hub
– as for the hub, even for the node i specified in -host the local IP.
Launched this , in the hub which is running we can see a message as

16:46:30.997 INFO – Registered a node

On the pc/vm which is acting as hub, pointing a browser to http://localhost:4444/grid/console we can see something as

You can see that we got one remote proxy here.

Every browser icon has a tooltip, for example we can see

In this case the protocol is Selenium.Platform , WIN10.

Browser name is chrome.

And then the max instances is 5 (it supports up to five concurrent tests).
All is ready, we can do our first grid test.

First, the code must be changed only in the part of the connection, we have now:

using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using System;

 namespace WebDriverDemo
    class Program
        static void Main(string[] args)
            //IWebDriver driver = new FirefoxDriver();
            IWebDriver driver = new RemoteWebDriver(new Uri("http://localhost:4444/wd/hub"),
                new DesiredCapabilities("firefox", "", new Platform(PlatformType.Linux)));
            driver.Url = "";
            var searchBox = driver.FindElement(By.Id("lst-ib"));
            searchBox.SendKeys("Donald Trump");

Note that we don’t need anymore

using OpenQA.Selenium.Firefox;

but is requested

using OpenQA.Selenium.Remote;

and we connect to the hub at localhost:4444/wd/hub , piloting a remote Firefox on Unix (DesiredCapabilities).

We have a remote Linux (Ubuntu) proxy with FireFox, so launching this code we can see on the remote Ubuntu instance:

The browser is opened, automatically goes to Google, the search term is inserted in the Google textbox.
We scratched only the surface, Selenium is an argument on which there are entire books: but for starters this article could be useful.

Categories: .NET, Selenium, Testing, Ubuntu, Vs2015

Differences in browsers engines under AngularJS

Working to updates on a AngularJS site, i discovered subtle differences.
I don’t know if there were these problems before, but certainly they raised while testing with Angular 1.6.5
First, if the user was switching the site language from English to Italian while working , saving a date Moment was not able to parse the date giving “Invalid date” using the latest Chrome and Firefox, while with Ie11 and Edge all ok.
In origin the code was (oh yeah, it uses the DOM objects instead of the binding..)

var testDate = moment($("#txtBirthDate").val()).format($scope.DateFormat.toUpperCase());
if (testDate === "Invalid date") {
    logWarning(localize.localizeText("DateNotValid"), null, true);
    return false;

For the first thing , using Visual Studio 2017 and starting the project i noticed that finally the breakpoints in javascript code are working also under Chrome, great thing:

Obvious , $scope.DateFormat.toUpperCase() is evaluated at runtime as YYYY-MM-DD for English and DD/MM/YYYY for Italian.
In order to work also with Chrome and Firefox this is the correct Moment syntax:

var testDate = moment($("#txtBirthDate").val(), $scope.DateFormat.toUpperCase()).format($scope.DateFormat.toUpperCase());

This code instead works without changes in all browsers:

var datBirthDate = moment($("#txtBirthDate").val(), $scope.DateFormat.toUpperCase()).toDate();
var BirthDate = datBirthDate.yyyymmdd();  // as requested for SQL Server

Then the other issue, an awkward issue.
The customers have the bad habit to press F5 or worse the browser refresh button in the pages, that in Angular does little sense.
In the site the other controllers (the ones not relatives to the home page) are loaded with ocLazyLoad (current version v1.0.10), in config.route.js the code was

}, {
    url: '/phones',
    config: {
        title: 'Phones',
        role: 'Administrator;PowerUser;User',
        templateUrl: 'app/tabelle/phones.html', 
        resolve: requireDependencies(['app/services/datacontextphones.js'], ['app/tabelle/phones.js']]),
        settings: {
            content: '<i class="fa fa-mobile"></i> {placeholder}',
            nav: 3,
            localizeKey: 'mnuPhones',
            minicontent: '<i class="fa fa-mobile" title="{placeholder}"></i>'
}, {

The function:

function requireDependencies(depContext, depMain) {
    return {
        resolvedData: ['$q', '$rootScope', '$ocLazyLoad', function ($q, $rootScope, $ocLazyLoad) {

and this code with Ie11 and Edge was working fine, the users could hit F5, the browser refresh button, and the page is refreshed without problems.
Instead with Chrome and Firefox:

After some struggle, the working code in that doesn’t use the function requireDependencies and all pages are surviving to the refresh in all browsers:

}, {
    url: '/phones',
    config: {
        title: 'Phones',
        role: 'Administrator;PowerUser;User',
        templateUrl: 'app/tabelle/phones.html', 
        resolve: {
            deps: ['$ocLazyLoad', function ($ocLazyLoad) {
                return $ocLazyLoad.load({
                    name: "phones",
                    files: [
        settings: {
            content: '<i class="fa fa-mobile"></i> {placeholder}',
            nav: 3,
            localizeKey: 'mnuPhones',
            minicontent: '<i class="fa fa-mobile" title="{placeholder}"></i>'
}, {

Categories: .NET, Angular, Javascript, Vs2017

Dump a .NET DataTable in VB.NET as XML file

If we have a DataTable named rstData in our VB.NET code:

Dim ds As New DataSet
ds.Tables(0).TableName = "ATableNameYouWant"

Categories: .NET, VB.NET

Not only my sites..

5-15-2017 11-49-43 PM

Categories: .NET


Followed by:Object reference not set to an instance of an object.
I was struggling in an old Asp.Net site, which is using Microsoft Ajax Toolkit, with this error.

In order to reduce the postbacks i used some jquery for partial page updates, and using a simple html select with a button for change the parameter to a REST call, i got this error.
The problem solution is very simple.. the HTML button tag by default causes a postback, and the error was caused from a null value in the Page_Load event of the behind code: the button type must be “button”, otherwise without specifying the type is considered as “submit”.

Then the HTML is:

<button id="cmdUpdateByFilter" onclick="updateSint();" type="button" class="Botton">Update</button>

Categories: .NET, Ajax, HTML5, VB.NET

Visual Studio 2015 Performance Profiler metabase error

Starting the Performance Profiler in order to analyze a web site i got the error “The website metabase contains unexpected information or you do not have permission to access the metabase ….”:

The solution is configured to run using the local IIS (of Windows 10).
In order to fix this problem on the Control Panel->Programs and in “Turn Windows features on or off”

must be activated the Windows Authentication

and the entire IIS6 Management Compatibility branch

Categories: .NET, Vs2015

Roslyn access denied error

Publishing a .NET 4.5 site on a normal provider, not Azure, i got the yellow screen of death “Access is denied” with “Cannot execute a program. The command being executed was \roslyn\csc.exe”.
Since the .NET 4.5 , Roslyn is the default compiler; Roslyn is interesting (even if i wrote code that was evaluating C# code years ago using Reflection) but i was in a hurry, i was needing to make the site working ASAP.
The quick & dirty solution is to delete from web.config the system.codedom section.

Categories: .NET, Vs2015

Vb6 software on Azure VM

There are still customers that uses old, aged software: for example, i have customers using my old program for truck transports, that uses a Microsoft Access file as database.
As i wrote in this post, this software in installed on a on-premise server, which was tipically Windows server 2003.
Now, these old servers (often recycled) are dying, the hardware today is more cheaper than in the past but an Windows Server 2012 license is still expensive for a small office.
So the idea: let’s try to migrate to Azure!
So i began an incredible amount of try & catch (errors..)
The application requires to send emails via CDO , with an attached pdf file generated from the Crystal Reports engine (used from the app for the printing activities).
In order to print via CDO is required a working email client; in the old Windows 2003 there was by default Outlook Express, instead from 2008 version in Windows Server there is no more an email client: this can be resolved installing Windows Mail, but it requires .NET 3.5
First error: using an Windows Server 2012 DataCenter NOT R2.
The main problem with the “normal” version is, IMHE (In My Humble Experience) that .NET 3.5 is not installable because you can’t use the downloadable 3.5 installer and this must be done from the Server Manager that complains about missing sources (for example see here, but i was not able to achieve the same result) : could be that attaching an ISO file (of Windows Server 2012) it works.
But i lose no more time and try creating instead an Windows Server 2012 R2 vm: same complain about the missing sources, but this time .NET 3.5 installed without issues.
The installation of Windows Mail was without problems and so for my app.
The only problem is the calendar for date input: my vb6 app uses mscal.ocx (perhaps a wrong choice) which is problematic.
For example in the setup.lst file generated from the vb6 package installer wizard the mscal is generated as

File10=@MSCAL.OCX,$(WinSysPath),$(DLLSelfRegisterEx),$(Shared),5/7/98 12:00:00 AM,90112,

But the DLLSelfRegisterEx must be changed in DLLSelfRegister otherwise the setup is not successful.
And in every case the problem is that the calendar was not displayed (interface in Italian):

The solution was to recreate from scratch the VM and create an vb6 installer WITHOUT mscal.ocx: it is already present in the Azure vm and trying to install another mscal.ocx causes big troubles in the registry; now the mscal.ocx is working ok.
Another curious thing was that in the vb6 code

With Flds
    .Item("") = boolUseSsl
    .Item("") = intSmtpAuth
    .Item("") = strUser
    .Item("") = strPwd
    .Item("") = strSmtpSvr
    .Item("") = intSendUsing
    .Item("") = intSvrPort
End With

“microsoft” was accidentally written with the initial “m” uppercase, so the email sending was not working in the new 2012 R2 server (instead in Windows Server 2003 yes!); after the correction, emails sent.