Add IIS URL Rewrite

By default IIS is missing the URL rewrite.

Looking at a fresh install of IIS admin view, the icon which should be found within the section, IIS, is missing.

Having gone through the sequence to add as detailed in the article Adding ASP.NET Features to IIS7.5, I expected to find it as an option here.

Adding ASP.NET Features in IIS 7.5 Including ASP.NET

But it’s not listed.

To add this visit the page and follow the instructions, downloading and running the module.

Here’s a view of the IIS admin screen with the URL Rewrite icon, sitting between the Server Certificates and Worker Processes on the bottom row of the IIS section.

Add IIS URL rewrite, icon added



Add Scroll Top Image

When the web page has scrolled down an offset distance show a scroll to top image.

When redesigning the VNTweb website, thinking about the longer article pages, I chose to add one of these.

Scrolling the page down shows on image in a fixed location. Clicking on this image shall scroll the page back to the top of the page, or a named div.

I wanted my scrolltop image to appear once the page had scrolled down by a measure.

Here’s what I used

  if ($VNTweb(this).scrollTop() > 100) { 
  } else { 

Once the page has scrolled down by 100 pixels then the scroll image becomes visible.

And for the image onClick scroll action I used the scroll from my article JQuery Page Scroll on Load, a few weeks ago.

  $VNTweb("html, body").animate({ scrollTop: 0 }, 600); 
  return false; 

You may wish to experiment with the distance scrolled before showing the image. Perhaps 100 pixels is too soon.

Another idea would be to hide and show the image at different values.

For example show the scroll to top image when the page has scrolled down a distance of 400 pixels, but hide once more when the distance reaches 300.

If you are looking for suitable images take a look at Font Awesome or Glyphicons.

Determine Subroutine Click Event Trigger

Using one sub-routine to handle more than one link button click event requires determination of which button click triggered the sub-routine.

I had an existing subroutine handling a link button. Examining the entries in a form, updating a database and sending an email. A second button was required on the form which would update the database but not send the email.

Options were:

  1. Clone the sub-routine omitting the email sending
  2. Two subroutines to handle the click events with each calling a common function where the difference between the two actions is to be determined. Or just the common block of code for saving the form values.
  3. One subroutine to handle the two click events with the email sending determined by which link button was clicked.

For a quick solution I chose option 1 – clone the subroutine.

However, with time available later I was interested in implementing option 3 – one subroutine handling two click events with a part of the code in the subroutine determined by which link button triggered the event.

In the code below the two link buttons are declared, followed by an outline subroutine to handle the clicking of the two buttons.

'Declare two link buttons with event handling
Dim WithEvents cmdSave as System.LinkButton
Dim WithEvents cmdAdd as System.LinkButton'Sub routine to handle the clicking of either button.
'Run common block of code in sub routine
'Determine event was triggered and run an optional block
Private Sub cmdLButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdSave.Click ,
  'common block of code here (update database)
  'Code here specific to one item
  If sender = cmdAdd  Then
    'send email to applicant confirming form submission
  End If
  If sender = cmdSave Then
    'send email to applicant confirming form submission
  End If
End Sub

A test is made to determine which of the two link buttons was clicked.

In the example above I have shown each as their own separate if statement. When I developed this further I replaced the if statements with a select.

Shown below is a part of the updated

missing the right buttons/commands, would be better to base this upon the GridView edit/update/delete automation

 <asp:GridView ID="gdvCU" runat="server"
    <asp:TemplateField ItemStyle-HorizontalAlign="left" ItemStyle-Width="80%">
        <asp:RadioButton ID="rbnOption" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.Text")  %>' GroupName='<%# DataBinder.Eval(Container, "DataItem.Value")  %>' Checked='<%# DataBinder.Eval(Container, "DataItem.Selected")  %>' AutoPostBack="true" OnCheckedChanged="DeselectSelected" />
    <asp:TemplateField ItemStyle-HorizontalAlign="Left" ItemStyle-Width="20%">
        <asp:LinkButton ID="cmdCU" runat="server" Text="Send" CommandName='<%# DataBinder.Eval(Container, "DataItem.Value") %>' CommandArgument='<%# DataBinder.Eval(Container, "DataItem.Value") %>' CausesValidation="false" Visible='<%# DataBinder.Eval(Container, "DataItem.enabled")  %>'></asp:LinkButton>
        <asp:Label ID="FruitId" runat="server" Text='<%# DataBinder.Eval(Container, "DataItem.FruitId") %>' Visible="false"></asp:Label>

The Associated subroutine to handle the above gridview and its submission.

Protected Sub cmdCURegister(ByVal sender As Object, ByVal e As GridViewCommandEventArgs) Handles gdvCU.RowCommand
      Select Case e.CommandName
        Case "Registered"
          'action here if visitor is registered
        Case "NotRegistered"
          'action here if visitor is not registered                      
      End Select
    End If

  Catch exc As Exception 'Module failed to load
    ProcessModuleLoadException(Me, exc)
  End Try
End Sub

What about option 2?

Having satisfied my interest with the common subroutine with a test to determine the source and choose the appropriate action I never implemented option 2.

Composite SQL Field with null Value Returns Blank

The intent was to join the address fields as a single returned value from a database query select. But I found that if one of these fields was null, the whole returned result was empty.

I had an address, in the usual way, across a number of database fields: address; town ; postcode and county.

I wished o let the database query do the work, joining the fields, as opposed to the VB/C# code.

The SQL query to join these fields as a single composite field value.

Shown below is my first version of the composite field value, derived from the individual address parameters.

‘Street: ‘ + building.address + ‘, Town: ‘ + + ‘, Postcode: ‘ + building.postcode + ” AS Location

My original expectation was that if one of these address fields was null then that part would be shown as blank.

For example with no town the returned entry might be:

Street: Broad Street, Town: , Postcode:  Rg1 1AA

I found that whilst I could readily create a string composed from the individual fields on occasion the result was empty, even though I knew at least one field to have a valid value.

Investigating I showed that if one of the fields was empty (null) then the whole combined field had a null value.

The building location was to show the address, as street, town and postcode.

‘Street: ‘ + building.address + ‘, Town: ‘ + + ‘, Postcode: ‘ + building.postcode + ” AS Location

As can be seen its a simple string addition of the individual fields.

However, if there was no entry in one of the fields, ie. it was null, then the whole result returned as an empty field, as opposed to the single empty entry.

To correct the empty result error I added an isnull test for each field, taking either the database value or an alternative presentational value, In this instance a couple of dashes to indicate that there is no entry.

‘Street: ‘ + ISNULL(building.address,’–‘) + ‘Town: ‘ + ISNULL(,’–‘) + ‘Postcode: ‘ + ISNULL(building.postcode,’–‘) + ” AS Location

Shown above is the previous example with the addition of the isnull.

For our earlier example this gives:

Street: Broad Street, Town: –, Postcode:  Rg1 1AA

Adding ASP.NET Features to IIS7.5

By default Windows 7 IIS is missing the features, shown above the IIS section in the control panel

The control panel is shown below with only the IIS options and Management options.

Adding ASP.NET Features in IIS 7.5

To add the features. Begin by opening the control panel and selecting from the Programs section the option Turn Windows features on and off.

Adding ASP.NET Features in IIS 7.5 Windows Features

Click on the checkbox for ASP.NET.


Adding ASP.NET Features in IIS 7.5 Windows Features add ASP.NET

There’s a dialogue window confirming that the amendment is taking place:

Please wait while Windows makes changes to features. This may take several minutes.

You may find that this takes a few minutes. Wait whilst the dialogue completes.

I have read that IIS is to be restarted for the change to show. However, for me it was sufficient to close the management window and reopen it once more.


Adding ASP.NET Features in IIS 7.5 Including ASP.NET


Whilst the control panel ASP.NET section is missing by default its easy to add it in, following the steps above beginning with the control panel.


Create Website Thumbnails from the Command line

Creating a new portfolio page for a website I was looking for a simple to use thumbnail creator.

The thumbnail creator should have the following criteria:

  •  minimum of steps, one would be ideal
  • easily repeatable
  • consistent output sizing

I wanted to avoid:

  • resizing the browser to specific dimensions for the next batch. Once closed reproducing the exact sizing from before is problematic
  • not reliant on an external reference, such as the old thumbnail service by Alexa, or the ShrinkTheWeb.

I knew that I could take a screenshot of the browser, either with one of the browser tools or a screen capture program. This could then be transferred to the Gimp for image editing and saving. Or maybe save the images and do a batch conversion with a tool such as XnConvert.

I wanted to keep the thumbnail creation both simple and easily reproducible.

Looking through my previous articles I one about taking screenshots from the command line using wkhtmltopdf.

neil@local:~$ wkhtmltoimage –width 1200 –height 1000

It was easy to put in the website address, an appropriate file name and click return. Done within a few seconds I had a thumbnail of a website capture and saved. Replace the website URLs to work my way through the list.

Create websites from command line: did find that pages employing flash had empty spaces. For example this one from Lily Oakes’ website, which incorporates content from YouTube.:

Create websites from command line:

Also one or two with sliders, which were taking longer to render, had missing content. These would be later visited using the slower more fiddly method with browser, screenshot and Gimp.


Hide Admin Messages from Subscribers

Do you want all your WordPress logged in users to see your system messages?

Messages declaring pending plugin updates, a WordPress core update, or a notification from a plugin, all visible to any logged in user.

Lets keep the info given to registered users of your website to a minimum. We don’t wish to tell them about the status of the website.

There are a couple of areas to target:

  • Admin notifications
  • The notification bar

WordPress provides hooks to actions covering both of these areas.

By checking the capabilities of the user we can determine whether we wish to show the info.

The restriction uses actions and filters added to the file functions.php in the theme.

Admin Notifications

Perhaps the most important.

Checking to see whether the user is able to update the core first, this function determines whether to show admin notifications.

function show_update_notice_admin_only()
    if (!current_user_can('update_core')) {
        remove_action( 'admin_notices', 'update_nag', 3 );
add_action( 'admin_head', 'show_update_notice_admin_only', 1 );

Notification Bar

At the top of the page there is the notification bar. Lots of content on this bar we don’t want non-admin users viewing.

So can we hide it ? – Yes, using filters.

This time we are testing to see if the user is unable to perform a couple of actions.

The first test is the management of options.  If the user is unable to do so then hide the admin notification bar.

Similarly the second test checks whether the user can update posts. If this isn’t possible then again the admin notification bar is hidden.

// show admin bar only for admins
if (!current_user_can('manage_options')) {
	add_filter('show_admin_bar', '__return_false');
// show admin bar only for admins and editors
if (!current_user_can('edit_posts')) {
	add_filter('show_admin_bar', '__return_false');


WooCommerce Cross-Sell and Upsell Products

Upsell and Cross-sell products are used in WooCommerce to increase product sales.

When do these two lists of products get shown?

Let’s begin by adding some products of each type to a product.

On the Product data section there are a number of tabs running vertically at the left with the associated configuration options in the remainder of the page.

WooCommerce Cross Sell and Upsell products: linked products

Click on the tab linked products to show the upsell and cross sell options.

Linked products are added by typing a few letters from the product name and making a selection from the resulting list.

WooCommerce Cross Sell and Upsell products: adding upsell product

In the screenshot above the upsell product of Chantenay Carrots is being added.


Upsell products are shown when viewing a single product’s detail, its description, images, price and attributes

WooCommerce Cross Sell and Upsell products: view product

In this view we are seeing an individual product with below two sets of products, the upsell products and the related products, based on what we have seen before.

The upsell products are premium versions of the product selected to view. In this instance I’m showing the higher priced purple spouting and kalettes.


The list of cross sell products appears when viewing your basket of items.

Having made our product purchases. Click to view the basket.

WooCommerce Cross Sell and Upsell products: view basket

In this view we are seeing the configured cross sell products of carrots and potatoes.

With a cross-sell product we wish to encourage the shop visit to buy something relevant to the items in the basket. I’ve chosen to show more vegetables but a steamer/saucepan to cook the vegetables would also be appropriate.

How to Refresh your Browser Cache

Sometimes  the browser needs to be refreshed.

When a web site’s files, images, CSS and JavaScript, have been changed its possible for the browser not to realise the change and to continue using its older cached version.

Many times I have made a change to a client’s website, advised them that the updates are completed only for them not to see the change.

Refreshing the page view will often not update the view.

To view the changes made to the associated website files can require a forced browser cache update.

What is the Browser Cache?

Browser website cache is the local storage of website components: images, scripts and CSS rendering files.

The aim is to store a local copy of the website components such that the next time the page is visited only one or two items may need to be downloaded.

This improves the load speed of the website.

Browsers and how to reset flush their cache:

CachingRefresh browser cache typical website timeline

The image above shows the details regards the timing for the downloading of the various components of a website.

a web a page allows a browser to

By caching elements of a website the browser saves on time regards to the download of those elements.

However, if one of these elements has been updated it may mean that the change isn’t showing.

If the browser is still using its older cached version then the page will look the same as before.

So, how to force the browser to reload it’s cached items, just as if it was the first time visiting the web page?

Whilst updating customer’s websites I sometimes find that the changes are not visible in their browser when reviewing the update.

For example if an image hasn’t changed, or as shown in the image above one of the website rendering CSS files is still the same then this file doesn’t need to be downloaded.

This means that the browser can render the page much quicker – it hasn’t had to wait for the file to be downloaded.

Its also lighter on your Internet plan.

Browser shows an old version – but my file has changed

Simply refreshing your browser view of a page may not be sufficient.

Browsers tend to like to work from their cached copy of website static files. Files such as images, script files and styling are generally considered to be static.

Refreshing the browser page will allow the server to regenerate the content, perhaps with any differences. But the underlying files will be kept.

So, how do I force the browser to refresh its cache? Reloading all of the websites files as if I was visiting the site for the first time.

Force Browser Refresh

The browser will try to limit the files which it downloads. However, his can mean that files which have been updated are not realised. Rendering n older version of the file.

This effect is most visible when an image or the CSS layout file have been updated.

This is most notable during the development phase of a website.

Listed below are a number of browsers with how to force the browser to refresh its cache. Sometimes clicking on the browser refresh or pressing the often used f5 key are just not enough

Refresh browser cache Firefox refresh

We need to tell the browser to forget anything that has previously been downloaded from the website should be forgotten and download afresh.

Researching this I found that comparable methods don’t exist across all of the browsers.


I have found with Firefox that if I follow the often stated recommendation to host down the shift key and to press the f5 key I usually open a new tab.

I have found that it is preferable to hold down the shift key and to then click on the refresh icon to the right of the address bar.

Whilst testing website I have found that server errors can be particularly irritating. Firefox will fail to get the note working content from the server, rather contributing to show the server error. This does eventually time out and function correctly indeed more.


For Safari versions 9 onwards pressing the command key and R will refresh the cache.

There is also the option to click on the reload icon (at the end of the navigation bar) whilst holding down the shift key.

Google chrome

Either CRTL + F5 or <SHIFT> + F5 will work.

This may also be done from the Settings. Having selected the settings, scroll down to the bottom of the list, expanding the section Advanced. Within Privacy and security click on the option Clear browsing data. The option we’re interested in is Cached images and files. Ensure this one is ticked, untick the remainder. click on the button CLEAR BROWSING DATA.

Internet Explorer

<CTRL> + refresh ought to suffice. But its not guaranteed. With IE the better option is to clear the cache either via the tools menu or F12 key.

You may find you need to use the tools options to properly clear the cache.

Click on the gear icon and in the popup window Internet Options within the sections Browsing History click on the Delete button. This opens a new window. Untick all items except Temporary Internet files and website files. Click on Delete.


IceWeasel is effectively Firefox. It therefore acts the same.


Opera doesn’t have the equivalent of clearing the cache for the current web page. Opera settings then select delete private data. Cache empty is for all.

Click on the menu in the top left corner. And click on Settings.

The Privacy & Settings page includes the option to Clear browsing data near the top, within the Privacy section.

Clicking on the link opens a pop-up window allowing selection of the items to clear. There’s an option to select how far back in time the selection shall affect.

Whilst not giving the option to select the current page this does give a good approximation.


From the Settings menu, select Configure Konqueror.

On the pop-up window Cache is shown in the left menu as a child item of Web Browsing. Click on this.

For me I was shown the message: This configuration section is already opened in Choqok.

I closed Choqok and tried once more.

There’s a single option, a button Clear Cache.


This is one of the <SHIFT> key plus toolbar refresh icon ones.


Click on the Vivaldi icon in the top left corner and select Tools and then Clear Private Data.

On the pop-up window select cache only and set the time to Past Hour. Click on Clear Browsing Data at the bottom of the window.


How to clear the Firefox cache

Opera Help: Cache

Empty the DNN Site Log

An excessively large SiteLog table is likely to have an impact on the performance of your website. Do you know how many entries there are and whether the older ones are being cleaned out?

I have found that the DNN Site log table can be prone to growing, unrestricted.

This can be brought about by the failure to set a day limit and not enabling the scheduled clean up task.

In the past I have found values in the site log which precede the given cut-off date. Often as a result of the number of days being reduced, but the SiteLog purge not running properly.

Maybe looking through the scheduled task notifications you are seeing messages which show the purge of the site log is failing.

Failure of the scheduled task to run is often a sign of a table which has grown too large and is timing out on the deletion.

Information about the site log table SiteLog can be gained via the admin SQL Console.

Empty the DNN site log: count number of rows

SQL is entered within the main text area and run by clicking on Run Script.

Take care! It is easy for an entered command to wipe table contents, beyond the intended results.

The size of the table, ie. the numbers of rows in the table, can be determined by running the command:

SELECT count(*) FROM SiteLog

It’s also possible to see if there are entries earlier than your set limits.

This can be done by running the command


Shown below a typical set of results, based upon a newly enabled sitelog, with the number of columns abbreviated for clarity.

DateTime Referrer Url UserAgent
21/03/2018 12:32:00 http://localhost/Admin/Site-Settings http://localhost/Default.aspx?TabId=67&language=en-GB Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
21/03/2018 12:32:00 http://localhost/ http://localhost/Default.aspx?TabId=56&language=en-GB Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
21/03/2018 12:33:00 http://localhost/Admin/Site-Settings http://localhost/Default.aspx?TabId=67&language=en-GB Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
21/03/2018 12:33:00 http://localhost/Admin/Log-Viewer http://localhost/Default.aspx?TabId=21&portalid=0&language=en-GB Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
21/03/2018 12:33:00 http://localhost/ http://localhost/Default.aspx?TabId=56&language=en-GB Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36

If there are entries preceding the cut-off date these may be deleted using

DELETE FROM SiteLog WHERE DateTime < given date

Dates are awkward to deal with. By default entries are stored in American date format. It is also anticipated that dates used will also be in this format too. Rather than adding formatting information when running these commands you may wish to simply accept the default format.

To ensure that you are going to delete the correct items try a selection first, based upon your date range

SELECT * FROM SiteLog WHERE DateTime < CONVERT(DATETIME, ’03/21/2018′)

From my example above I am expecting this to return no results, which is the case.

Whilst setting the date as 22/03/2018 gives:

DateTime Referrer Url UserAgent
21/03/2018 12:32:00 http://localhost/Admin/Site-Settings http://localhost/Default.aspx?TabId=67&language=en-GB Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
21/03/2018 12:32:00 http://localhost/ http://localhost/Default.aspx?TabId=56&language=en-GB Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
21/03/2018 12:33:00 http://localhost/Admin/Site-Settings http://localhost/Default.aspx?TabId=67&language=en-GB Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
21/03/2018 12:33:00 http://localhost/Admin/Log-Viewer http://localhost/Default.aspx?TabId=21&portalid=0&language=en-GB Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0
21/03/2018 12:33:00 http://localhost/ http://localhost/Default.aspx?TabId=56&language=en-GB Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36

You may also wish to sort by the datetime field descending, just to get the newer entries

SELECT TOP 20 * FROM SiteLog WHERE DateTime < CONVERT(DATETIME, ’03/21/2018′) ORDER BY DateTime DESC

It’s possible with too many entries in the SiteLog that the deletion of a range of rows will timeout.

You may wish to purge the SiteLog table. I have found that doing this via the DNN SQL control console can lead to time outs and failure to action.

If the truncation of the table times out or fails then you may find that it’s Better to perform the action via the SQL Server Management Studio, if this is available to you .

I navigate to the required database table view and click on the New Query button.

Enter the following


Refresh your table view to see the change in the number of records.

DotNetNuke can require a restart of the application to reflect changes made to the database.

With DNN 9 the site log has been removed. Although it can be added back in if you wish.

Reviewing an older site I observed that the site log still existed.

Without the original admin configuration, it’s not possible to empty the log table by following the older practices to restrict the number of days or to turn off the site log.

I chose to use the SQL truncation detailed above to empty the site log table.


A Site Log module: