IIS 8 Web Site in Windows 8 externally accessible to the World

Today I needed to allow a per to access an application that’s under development. Instead of buying a cheap ASP.NET hosting account I decided to host the app on my local IIS 8 server. The process to get this configured and working was somewhat exciting since I learned new things along the way.

I’ll show in this post the steps I followed to have this working as expected…

My setup:

  • Windows 8 running inside a virtual machine in Parallels 8 with IP address 192.168.1.107;
  • ASP.NET MVC 4 app deployed in the Default Web Site in IIS 8 that is configured to accept incoming connections in the standard port 80;
  • Linksys WAG200G router/modem connected to the outside/external World.

Steps to follow:
1 - Go to the router’s management interface. In my case it’s located in the address 192.168.1.1.

2 - You’ll need to set a port forwarding configuration. In my case it’s located in Applications & Gaming / Single Port Forwarding. It’ll vary slightly depending on your router vendor and model.

Application: HTTP
External Port: 80
Internal Port: 80
Protocol: TCP
IP Address: 192.168.1.107 (your Windows/IIS machine IP address)
Enabled: True (checked)

Linksys WAG200G Single Port Forwarding configurationFigure 1 - Linksys WAG200G Single Port Forwarding configuration

Make sure to hit the Save Settings button way bellow the page.

3 - Go to Windows 8 Control Panel / System and Security / Windows Firewall / Turn Windows Firewall on or off.
Turn off Windows Firewall for Private Networks.

Turning off Windows 8 Firewall for Private NetworksFigure 2 - Turning off Windows 8 Firewall for Private Networks

4 - Take note of your internet IP address. You can see it in the router’s status page. In my case it’s located in Status / Gateway. Again where you’ll find this info will vary depending on your router vendor.

Taking note of the internet/Gateway IP that uniquely identifies the machine on the internetFigure 3 - Taking note of the internet/Gateway IP that uniquely identifies the machine on the internet

You can also see your current IP Address using Gmail’s Last Account Activity report if you happen to have a Gmail account of course.

5 - Open a browser window and type your internet Gateway IP address taken in step 4. You should be presented with the beautiful IIS 8 default web page if you have no app deployed in the Default Web Site; otherwise you should see your app’s default page/login view.

IIS 8 Default Web Site pageFigure 4 - IIS 8 Default Web Site page

That’s it! Now the web site/app is available externally to any user in any part of the WORLD directly from my development machine.

Anytime I want I can hit Publish from within Visual Studio 2012 and deploy directly to the local IIS 8 server. The user that knows my IP address can then see my ongoing work remotely and free of charge for now.

Note 1
I do not have a static IP address, that is, my ISP here in Brazil (Oi Velox) gives me a dynamic IP address. This means that if there’s a power outage or if the router resets for whatever reason I’ll get a different address – it’s really important to know about this. To overcome such limitation there are some services that can help. One of them is No-IP. It basically allows you to access your computer by a hostname instead of an IP address by using dynamic DNS. They have a free utility app that runs in the background and that automatically syncs your current dynamic IP address with your custom hostname defined in No-IP service.

Excerpts from No-IP site:

What is a hostname?
A hostname is a name given to a computer to make connecting to it easier. Instead of typing out a long IP address you can enter the hostname followed by the domain name, such as myhostname.no-ip.com.

What is dynamic DNS?
Dynamic DNS makes it possible to connect to computers with dynamic IP addresses without needing to know the actual IP address.

They have a free account available with some limitations but it’s worth trying anyway.

Note 2
If for some reason your ISP blocks the default IIS port 80 (something common – hooray! not in my case today) you can try forwarding from a different external port like 8888 in step 2 above. In this case, you’d have to specify this port address when trying to access your IIS server. For example:

189.xxx.xxx.xxx:8888

where 189.xxx.xxx.xxx is your internet IP address.

Data binding view values to an array parameter in ASP.NET MVC

If you want the source codez, jump here.

This looks like something so easy to be done and at the same time I guess a lot of people fail the first time they try to get this working. This question at StackOverflow proves that. So to help the fellow developers out there I put together a concise ASP.NET MVC 4 sample application to show how to data bind/postback view values to an array parameter in an controller action method. I show two ways of doing this: using a traditional/full postback and an AJAX/partial postback. This way you can choose the best option for you.

Use case
User wants to be able to select 3 values ( at least 1 being mandatory Surprised smile ) in the view using dropdowns and data bind the selected value(s) to an array that will be treated inside the controller.

User Interface
While implementing the code I thought why not make the app a little bit fancier and give it some meaning and so I complemented the sample with color picker dropdowns. This is the UI:

ASP.NET MVC Array Data Binding sample app UI

Code
ASP.NET MVC needs the generated form elements to follow a certain format so that the model binder can do its job, that is, understand what you’re trying to do; otherwise when you debug the code you’ll just get a null value in the array parameter or ViewModel array property inside you controller action. This means that the model binder didn’t understand your posted data and I’m sure you thought it would. I’ve already been in this situation…

So the question is: How to make the model binder understand the view data? Let’s get to the code…

The sample’s code is well documented, so I’ll just copy/paste the important parts here. Just read the comments to understand what’s going on…

In the view side, you must create the input elements following this format:

@* Pay special attention to how we must name the form fields.
selectedColors is the name of a parameter defined in the controller action that will receive the form values. It’s necessary to suffix the name with [n], where n must be zero-based and unbroken. *@ @for (int i = 0; i < 3; i++) { @Html.DropDownList("selectedColors["+i+"]", Model.Colors, "-- Pick a Color --") }

In the controller side, you must have an action method with an array parameter named exactly like the name given to the dropdowns on the view side ( selectedColors ) like this:

/// <summary>
/// This action method works with a simple int[] array that's not part of a ViewModel.
/// </summary>
/// <param name="selectedColors">Simple int[] array</param>
/// <returns>ArrayPostResult view</returns>
[HttpPost]
public ActionResult TestArrayPost(int[] selectedColors)
{
    if (Request.IsAjaxRequest())
    {
        ViewBag.PostBack = "AJAX";

        return PartialView("ArrayPostResult", selectedColors);
    }

    ViewBag.PostBack = "Full";

    return View("ArrayPostResult", selectedColors);
}

The above code should take care of handling the full postback scenario.

To do an async/partial postback using AJAX you can use this jQuery code as an example:

$("#submit-ajax").click(function () {

    var selectedColors = [];

    // For each select HTML element/dropdown,
    // push its selected value into selectedColors
    $('select option:selected').each(function () {
        selectedColors.push($(this).val());
    });

    $.ajax({
        type: "POST",
        url: "/Home/TestArrayPost",
        dataType: "html",
        traditional: true,
        data: { selectedColors: selectedColors },
        success: function (response) {

            $("#result").html(response).fadeIn();

            // Hiding the GO back button...
            $("#result").find("#go-back").hide();

        },
        error: function (xhr, textStatus, exceptionThrown) {
            $('#result').html(exceptionThrown);
        }
    });
});

Note
If you want to postback the values to an array property that’s inside your ViewModel, for example:

public int[] SelectedColors { get; set; }

You can do this in the view side:

@for (int i = 0; i < 3; i++)
{
    @Html.DropDownListFor(m => m.SelectedColors[i], Model.Colors, "-- Pick a Color --")
} 

Then on the controller side, you’d have this:

[HttpPost]
public ActionResult TestArrayPost(ColorsModel model)
{
    if (Request.IsAjaxRequest())
    {
        ViewBag.PostBack = "AJAX";

        return PartialView("ArrayPostResult", model.SelectedColors);
    }

    ViewBag.PostBack = "Full";

    return View("ArrayPostResult", model.SelectedColors);
}

Source code
The code uses a bit of jQuery to control the UI logic and to postback the values through AJAX.

It’s hosted at GitHub and so you can navigate through it easily here.

You can download the Visual Studio 2012 solution here:

https://github.com/leniel/AspNetMvcArrayDataBinding/archive/master.zip

Hope it helps.

References
To implement this sample app I Googled some of the concepts employed like setting the background-color of select/dropdown options based on the option’s text. Pretty interesting stuff…

The following is a list of links that helped me:

Model Binding To A List
ASP.NET Wire Format for Model Binding to Arrays, Lists, Collections, Dictionaries
Drop-down Lists and ASP.NET MVC
@Html.DropDownListFor; How to set different background color for each item in DDL?
How do I convert an enum to a list in C#?

SignalR OnDisconnected Task and Dependency Injection with Castle Windsor - Hybrid lifestyle to the rescue

Today I faced a Castle Windsor dependency injection problem in an ASP.NET MVC app. The problem happened when using SignalR.

While implementing some UI real time user interaction I needed to have my persistence facility (Database context) injected inside my SignalR Hub class.

I Googled and found this awesome and to the point post by Mira Javora:

SignalR-Dependency Injection using Castle.Windsor

With the code he provided I was able to configure SignalR’s dependency resolver and everything was working as expected as Mira showed in his post.

In my case two objects are being injected in the Hub class:

public class AssessmentHub : Hub
{
    private MyContext _database { get; set; }

    private ILogger _logger { get; set; }

    public AssessmentHub(MyContext database, ILogger logger)
    {
        _database = database;
        _logger = logger;
    }

...
}

They were being properly injected in my own Hub class methods but things started to go wrong when SignalR’s OnDisconnected method was being called:

public override Task OnDisconnected()
{
    try
    {
        Guid connectionId = Guid.Parse(Context.ConnectionId);
// Database was null here! Sad smile
var client = Database.HubConnections.Single(hc => hc.ConnectionId == connectionId); UnlockChapterAndUpdateClients(client); Database.HubConnections.Remove(client); Database.SaveChanges(); } catch (Exception ex) { Logger.Error(ex.Message, ex); } return base.OnDisconnected(); }

This was the error I was getting:

HttpContext.Current is null. PerWebRequestLifestyle can only be used in ASP.Net.

The OnDisconnected method is an asynchronous method and as such it runs under a background thread ( not the one processing the request ). ASP.NET controls the threads and makes sure that only one thread is processing the request. This way HttpContext and as a consequence my _database injected object is null inside that method.

After some thinkering I remembered that I had my Persistence Facility registered PerWebRequest:

public class PersistenceFacility : AbstractFacility
{
    protected override void Init()
    {
        Kernel.Register(Component.For<MyContext>().          
            LifeStyle.PerWebRequest);
    }
}

Then, I Googled a little bit more and found this StackOverflow question:

Castle.Windsor lifestyle depending on context?

User Cuong Le shared a great post by Mauricio Scheffer called:

Hybrid lifestyles in Windsor

His post describes exactly what I needed (an Hybrid lifestyle ), that is, a way of keeping using the PerWebRequest life style when HttpContext is available but then resort to Transient lifestyle when it’s not.

An hybrid lifestyle is one that actually blends two underlying lifestyles: a main lifestyle and a secondary lifestyle. The hybrid lifestyle first tries to use the main lifestyle; if it's unavailable for some reason, it uses the secondary lifestyle. This is commonly used with PerWebRequest as the main lifestyle: if the HTTP context is available, it's used as the scope for the component instance; otherwise the secondary lifestyle is used.

I then grabbed Mauricio’s NuGet package Castle.Windsor.Lifestyles and changed my Persistence Facility code to:

public class PersistenceFacility : AbstractFacility
{
    protected override void Init()
    {
        Kernel.Register(Component.For<MyContext>().          
            LifeStyle.HybridPerWebRequestTransient());
    }
}

I’m back in business now. Call me

Updated PowerShell script to insert copyright notice/banner/header in all source code files

In a recent post I described how one could insert a copyright banner in all source code files located on a given path. You can read all the details about it here: Inserting copyright notice/banner/header in all source code files with PowerShell script

During the past month or so I updated that PowerShell script to give it even more power. In the Notes section of that post I mentioned this point:


  • Beware that if you run the script twice it'll add the copyright notice twice in each file

With this updated version (see the highlighted parts) I’ve overcome such limitation.

I’m now also using the built-in Powershell Filter keyword to filter the files, that is, processing only .cs files (C# code files) excluding some other files that have the .cs extension but that have a given naming pattern. I exclude those files because it doesn’t make sense to add copyright to them and because in some cases it would break the build.

Here’s the updated PowerShell script with comments to help you understand what’s going on in each line:

param($target = "C:\MyProject\trunk", $companyname = "Leniel’s Software House")

#[System.Globalization.CultureInfo] $ci = [System.Globalization.CultureInfo]::GetCultureInfo("pt-BR")

[System.Globalization.CultureInfo] $ci = [System.Globalization.CultureInfo]::GetCurrentCulture

# Full date pattern with a given CultureInfo
# Look here for available String date patterns: http://www.csharp-examples.net/string-format-datetime/
$date = (Get-Date).ToString("F", $ci);

# Header template
$header = "//-----------------------------------------------------------------------

// <copyright file=""{0}"" company=""{1}"">

// Copyright (c) {1}. All rights reserved.

// <author>Leniel Macaferi</author>

// <date>{2}</date>

// </copyright>

//-----------------------------------------------------------------------`r`n"

function Write-Header ($file)
{
    # Get the file content as as Array object that contains the file lines
    $content = Get-Content $file
    
    # Getting the content as a String
    $contentAsString =  $content | Out-String
    
    <# If content starts with // then the file has a copyright notice already
       Let's Skip the first 14 lines of the copyright notice template... #>
    if($contentAsString.StartsWith("//"))
    {
       $content = $content | Select-Object -skip 14
    }

    # Splitting the file path and getting the leaf/last part, that is, the file name
    $filename = Split-Path -Leaf $file

    # $fileheader is assigned the value of $header with dynamic values passed as parameters after -f
    $fileheader = $header -f $filename, $companyname, $date

    # Writing the header to the file
    Set-Content $file $fileheader -encoding UTF8

    # Append the content to the file
    Add-Content $file $content
}

#Filter files getting only .cs ones and exclude specific file extensions
Get-ChildItem $target -Filter *.cs -Exclude *.Designer.cs,T4MVC.cs,*.generated.cs,*.ModelUnbinder.cs -Recurse | % `
{
    <# For each file on the $target directory that matches the filter,
       let's call the Write-Header function defined above passing the file as parameter #>
    Write-Header $_.PSPath.Split(":", 3)[2]
}
Hope you make even better use of such a pearl that comes in handy from time to time.

Mp3tag and its useful actions like Replace with regular expression and Guess values

Every once in a while I’m in a situation where I need to refresh my mind about how to work with regular expressions and guess values in Mp3tag to batch process lots of MP3 in a single shot… I’ll try to keep this post as a reference for the artifices I use with Mp3tag so that I can get back here and see what and how I did to format my MP3 tags the way they should be.

Mp3tag - The Universal Tag EditorMp3tag is IMHO the best MP3 tag editor out there. I’m so satisfied with it that I stopped trying to find a better tool. Nonetheless, I’m open to recommendations…

Mp3tag is a powerful and yet easy-to-use tool to edit metadata of common audio formats where it supports ID3v1, ID3v2.3, ID3v2.4, iTunes MP4, WMA, Vorbis Comments and APE Tags.

It can rename files based on the tag information, replace characters or words in tags and filenames, import/export tag information, create playlists and more.

I’ve been writing about MP3 in this blog. If you’re interested, you can check past posts here

As I commented above, to refresh my mind I tend to look for this post I wrote some time ago: More MP3 guessing pattern with Mp3tag in Mac OS but I decided to compile future endeavors in this area in a single post. I hope you enjoy.

This time I’m using Mp3tag in the Windows 8 side inside a Parallels Desktop virtual machine.

OK. After some formalities, let’s complete these five basic steps needed in every use case I’ll present in this post:

1 - Click the change directory button and navigate to the folder where you store the MP3s you want to edit.

Mp3tag Change Directory button

2 - Select the files you want to edit. I just press Ctrl + A to select all the files. You can also hold Ctrl to select file by file.

3 - Click the Actions (Quick) button.

Mp3tag Actions (Quick) button

4 - Follow the use cases…

Removing year between parenthesis from file name

Guessing values for Artist and Title from file name

5 - DO NOT FORGET to click the Save button after executing the actions of each use case so that the changes get applied to the files; otherwise you’ll lose the edits. Confused smile

Mp3tag Save button

Use cases

Removing year between parenthesis from file name

Mp3tag Filename with Year between parenthesis

After clicking the Actions button, select Replace with regular expression, select the _FILENAME field and enter the regular expression \( 2o12 \). Press OK and you’re done:

Mp3tag File name with Year between parenthesis regex

Guessing values for Artist and Title from File name

Mp3tag Guess Values for Artist and Title from File name

As you see the MP3 files don’t have Artist and Title information. This is bad. If you use services like Last.fm to keep track of the music you’ve been listening to, you won’t be able to scrobble given the missing metadata. Of course you can fill the info by hand (Oh Lord! How boring and time consuming this task is). There’s Mp3tag to the rescue.

Taking the previous use case as a necessary step to format the file name accordingly…

After clicking the Actions button, select Guess values, in Source format enter %_filename%, in Guessing pattern enter \%artist% - %title%. Press OK and you’re done:

Mp3tag Guess Values for Artist and Title from File name regex

References

MP3 Tag - The Universal Tag Editor Help pages

JavaScript regex + jQuery to allow only English chars/letters in input textbox

Yesterday I answered this question at StackOverflow. The questioner wanted this:

How to allow only English, numeric and special chars in textbox using jQuery or JavaScript?

My answer was this:

$('#mytextbox').bind('keyup blur', function () {
    $(this).val($(this).val().replace(/[^A-Za-z]/g, ''))
});

It has a flaw because if you test it, you’ll see that every time a disallowed character is typed, the keyboard caret/text cursor goes to the end of the textbox. This is something that shouldn’t happen. Aristos mentioned something that I hadn’t tested: “the problem with your answer is that if you try to type something in the middle of the text, the cursor moves to the end.” He is absolutely right. You can test it below. Click the Result tab and type a digit like 7 or some other disallowed char in the middle of the textbox text to spot the problem:

OK – of course there must be a solution to this annoying problem and I couldn't miss the opportunity to play with it to find something that just works as expected. This answer by Ender helped me get there. The following code is what I came up with. I commented the code so it should be easy to understand what's going on:

$("#mytextbox").on("keypress", function (event) {

    // Disallow anything not matching the regex pattern (A to Z uppercase, a to z lowercase and white space)
    // For more on JavaScript Regular Expressions, look here: https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Regular_Expressions
    var englishAlphabetAndWhiteSpace = /[A-Za-z ]/g;

    // Retrieving the key from the char code passed in event.which
    // For more info on even.which, look here: http://stackoverflow.com/q/3050984/114029
    var key = String.fromCharCode(event.which);

    //alert(event.keyCode);

    // For the keyCodes, look here: http://stackoverflow.com/a/3781360/114029
    // keyCode == 8  is backspace
    // keyCode == 37 is left arrow
    // keyCode == 39 is right arrow
    // englishAlphabetAndWhiteSpace.test(key) does the matching, that is, test the key just typed against the regex pattern
    if (event.keyCode == 8 || event.keyCode == 37 || event.keyCode == 39 || englishAlphabetAndWhiteSpace.test(key)) {
        return true;
    }

    // If we got this far, just return false because a disallowed key was typed.
    return false;
});

$('#mytextbox').on("paste", function (e) {
    e.preventDefault();
});

Try it below:

Now you can type in the middle of the text and the text cursor should maintain its position.

The above version allows accented chars like á, é, â, ê, etc…

Note also that there’s a new event handler function (paste) attached to the input textbox. This removes the possibility of user pasting text in the textbox.

If you want to allow numbers/digits or any other special characters, it’s just a matter of updating the regular expression pattern. For example: if you want to allow digits from 0 to 9, just use this regex pattern:

var englishAlphabetAndDigits = /[A-Za-z0-9 ]/g;

Full code:

$("#mytextbox").on("keypress", function (event) {

    // Disallow anything not matching the regex pattern (A to Z uppercase, a to z lowercase, digits 0 to 9 and white space)
    // For more on JavaScript Regular Expressions, look here: https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Regular_Expressions
    var englishAlphabetDigitsAndWhiteSpace = /[A-Za-z0-9 ]/g;

    // Retrieving the key from the char code passed in event.which
    // For more info on even.which, look here: http://stackoverflow.com/q/3050984/114029
    var key = String.fromCharCode(event.which);

    //alert(event.keyCode);

    // For the keyCodes, look here: http://stackoverflow.com/a/3781360/114029
    // keyCode == 8  is backspace
    // keyCode == 37 is left arrow
    // keyCode == 39 is right arrow
    // englishAlphabetDigitsAndWhiteSpace.test(key) does the matching, that is, test the key just typed against the regex pattern
    if (event.keyCode == 8 || event.keyCode == 37 || event.keyCode == 39 || englishAlphabetDigitsAndWhiteSpace.test(key)) {
        return true;
    }

    // If we got this far, just return false because a disallowed key was typed.
    return false;
});

$('#mytextbox').on("paste", function (e) {
    e.preventDefault();
});

Here’s an updated jsFiddle that allows digits:

It’s really impressive what some small amount of JavaScript and jQuery code allows you to do on the client side. Actually if you care there are more comments than codez… Surprised smile

There’s no doubt JavaScript and JQuery will reign in the years to come.

About the code
As everything in software the above piece of code needs more testing. If you find a bug or some functionality that is missing, just leave a comment.

References
JavaScript Regular Expressions Guide by Mozzila.org

Delete Blogger Navbar section/widget from your blog template code

In the past I used to just hide Blogger’s navbar widget with some CSS code but it was still there being loaded in the HTML code. This approach is inefficient because I really don’t want the navbar. So why should it still be there in the code taking some precious time to load and impacting the user experience?

Blogger navbarFigure 1 - Blogger navbar

In my case when I looked at the Layout section of my blog in Blogger dashboard I saw that the navbar section was locked (see the locked=’true’ in Figure 2) which means I could not delete it in the Layout screen. So there’s only one option to really get rid of it and it is through the widget code.

If you look carefully you’ll note that the navbar’s code loads some JavaScript files as the Google Plus One plusone.js file. This is impacting my page load speed because I’m already loading the plusone script somewhere else since I have a customized template. This leads to duplicate requests for the same JavaScript file. This is really really bad. There’s no need for it.

So I was after a way of removing the navbar forever; not just hiding it with CSS. I then found a way of doing it but it didn’t work for me. Blogger redesigned its interface and maybe this is the problem.

Then I just thought: what if I try to select the navbar section code and delete it and hit save on the HTML template – who knows… this can work out. What’s the result: it does work out.

How to do it? Follow these 10 simple steps…

1 - First save a backup copy of your blog template for the case where something goes wrong;

2 - Go to Blogger dashboard and select Template in the menu on the left;

3 - Hit the Backup / Restore button at the screen top right and save a backup copy of your layout;

4 - In the Template screen, click Edit HTML button;

5 - Click the checkbox Expand Widget Templates;

6 - Hit Ctrl + F and find the string ‘navbar’;

7 - Select the section code like the one shown in the following screenshot:

Selecting the navbar section/widget code while editing the blog’s template HTML codeFigure 2 - Selecting the navbar section/widget code while editing the blog’s template HTML code

8 - Hit delete on the keyboard;

9 - Click the Save template button in orange. You should get this message:

Warning message informing that deleting the navbar widget cannot be undoneFigure 3 - Warning message informing that deleting the navbar widget cannot be undone

10 - Click Delete widgets button and you’re done. Smile

Now your page will load a bit faster and this is pretty nice for the user visiting your blog.