Improve your JavaScript with Web Essentials and JSHint

_This is a cross-post of an _article over on the Canadian Developer Connection

Visual Studio has some great features to help you write better JavaScript. With Visual Studio 2013, JavaScript is a first class citizen with support for features like IntelliSense and code snippets.

With the Web Essentials extension, you get even more great features to help improve your JavaScript. Web Essentials is a Visual Studio plugin that every web developer should have installed. The list of productivity features is huge.

One feature that I have been using a lot lately is the integration with JSHint.

What is JSHint?

JSHint is a source code analysis tool for JavaScript. It can analyze your JavaScript code and flag common misuses or suspicious code. You can think of it as FxCop.aspx) for JavaScript.

How does it work?

Once Web Essentials is installed, simply right click on either a JavaScript file or a folder containing JavaScript files and select Web Essentials –> Run JSHint from the menu.

 

The output from JSHint will be listed as Messages in the Error List. If the Error List is not visible, you can show it by selecting View –> Error List from the main menu.

In this example, we can see that I have a method that is never used and a missing semi-colon on line 5.

JSHint has a long list of rules that it checks against. Try not to take it personally if your Error List contains a large number of JSHint. After all, JSHint is just trying to help.

Web Essentials will also automatically run JSHint against any JavaScript files that you have open. Every time you save a JavaScript file, JSHint is re-run and the Error List is updated. I have started to keep a close eye on the Error List when making changes to JavaScript files.

JSHint Options

You might not agree with some of the things that JSHint points out in your code, and that’s okay. You have the option to change JSHint options globally (for all Visual Studio solutions and projects) by selecting Web Essentials –> Edit global JSHint settings (.jshintrc) from the main Visual Studio menu.

The JSHint settings is simply a text file containing a JSON object that will be passed on to JSHint when it runs. The configuration options are all very well documented on the JSHint website, with a complete list of options here.

JSHint Options – Solution Level

You might prefer to configure JSHint options for a particular project and share those settings with your team. To do this, simply create a file named .jshintrc in the root folder containing your JavaScript files.

Note: Creating a file that starts with a . can be difficult from Windows Explorer or from Visual Studio. The easiest way to create this file is to open a command prompt and enter _echo.>.jshintrc. _Once the file is created, include it in your Visual Studio project.

In this file, set whatever JSHint options you want. For example, if for some reason you wanted to allow missing semi-colons you could set the asi option to true.

Now all you need to do is add the file to source control and your settings are shared across your development team.

JSHint Options – File Level

You also have the option to override JSHint options at the file level using special comments.

For example, you could allow missing semi-colons for a specific file by adding /* jshint asi:true */to the top of the file.

Summary

The JSHint integration available in Visual Studio Web Essentials is a great tool to help improve the JavaScript code in your web project. Give it a try and see how much it helps you and your team.

Seeding Entity Framework Database from CSV

Ever since Entity Framework Code First was released, we have had a very simple and convenient mechanism for seeding our databases. Most examples show us only how to seed the database by adding a few items directly from .NET code. This approach may be cumbersome if we are dealing with a larger amount of data. A good example of this is populating tables for Countries and Provinces/States. In this post, I will show how we can populate data from CSV files.

Assume our model consists of 2 classes: Country and ProvinceState.

public class Country
{
public int Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public virtual IList<ProvinceState> ProvinceStates { get; set; }
}

public class ProvinceState
{
public int Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }

public virtual Country Country { get; set; }
}

Our database context simply has a DbSet for both classes:

public class LocationContext : DbContext
{
public IDbSet<Country> Countries { get; set; }
public IDbSet<ProvinceState> ProvinceStates { get; set; }

}

1. Seeding with Code First Migrations

If you are using Code First Migrations, you can seed our database by adding code to the Seed method of the migration’s Configuration class. The advantage of using this method is the Seed method is executed at the time the database is updated instead of at runtime. The method will be executed anytime a developer runs the Update-Database command or anytime we deploy a new version of the application using Web Deploy.

You can learn how to setup and use Code First Migrations over on MSDN.

Loading Data from CSV

First, let’s create a CSV named countries.csv that contains the data we want to load into our Countries table. The file might look something like this:

We will also create a second CSV file named provincestates.csv with the headers CountryCode, Code, and Name:

Next, we will include these files in our project in Visual Studio and set the Build Action to Embedded Resource for both files.

Install the CsvHelper Nuget package, a handy package for reading data from csv files.

Install-Package CsvHelper

Now we will modify the Seed method as follows:

protected override void Seed(SeedingDataFromCSV.Domain.LocationContext context)
{

Assembly assembly = Assembly.GetExecutingAssembly();
string resourceName = "SeedingDataFromCSV.Domain.SeedData.countries.csv";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
CsvReader csvReader = new CsvReader(reader);
csvReader.Configuration.WillThrowOnMissingField = false;
var countries = csvReader.GetRecords<Country>().ToArray();
context.Countries.AddOrUpdate(c => c.Code, countries);
}
}

resourceName = "SeedingDataFromCSV.Domain.SeedData.provincestates.csv";
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
{
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
{
CsvReader csvReader = new CsvReader(reader);
csvReader.Configuration.WillThrowOnMissingField = false;
while (csvReader.Read())
{
var provinceState = csvReader.GetRecord<ProvinceState>();
var countryCode = csvReader.GetField<string>("CountryCode");
provinceState.Country = context.Countries.Local.Single(c => c.Code == countryCode);
context.ProvinceStates.AddOrUpdate(p => p.Code, provinceState);
}
}
}
}

Now any time we run the Update-Database command, the Countries table will be synchronized with the data in the countries.csv file.

And the ProvinceStates table will be synchronized with the data in the provincestates.csv file.

This sample code is available on GitHub:

dpaquette/SeedingDatabaseFromCSV

Seeding with a Database Initializer

Another option for seeding data is to create a database initializer for your context. The database initializer also has a seed method where you could use the same code as above to load data from a CSV file.

You can find more information on here.

Simple Delete Confirmation in ASP.NET MVC

In this post, I will present a simple implementation of the Action-Confirm Design Pattern in ASP.NET MVC 5.

Deleting an Entity

Consider a simple listing of people in a grid as created by right clicking on the Controllers folder, selecting Add –> Controller, then selecting MVC Controller with views, using Entity Framework.

When we view the list of people, we see a Delete link for each row.

When we click Delete, we are taken to a Delete confirmation page.

The user experience here is acceptable, but in my opinion, navigating to a new page breaks the user’s flow a little too much. I think the same would be true if we used a modal dialog instead.

Action-Confirm Design Pattern

Lately, I have been using the Action-Confirm Design Pattern for entity delete actions in my applications. This pattern offers a less intrusive option than a traditional confirmation dialog / confirmation page.

When the user clicks the Delete icon [or link] it transforms into a Confirm button that looks distinctively different. The user can now either click the Confirm button to proceed with the action or click outside it (or press Esc) to revert to the previous state.

Using this pattern, when we click the Delete link, the delete link is replaced with a Confirm Delete button. If the user does not want to delete the item, they can press escape or click anywhere else on the document to cancel the action. When an item is successfully deleted, the row fades out and is removed from the page.

Here is the new Index.cshtml file that accomplishes this.

@model IEnumerable<ActionConfirmSample.Models.Person>

@{
ViewBag.Title = "Index";
}

<style>
.delete-section {
display: inline;
}

</style>


<h2>Index</h2>
@Html.AntiForgeryToken()
<p>
@Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.FirstName)
</th>
<th>
@Html.DisplayNameFor(model => model.LastName)
</th>
<th></th>
</tr>

@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
@Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
@Html.ActionLink("Details", "Details", new { id=item.Id }) |
<div class="delete-section" >
<a class="delete-link" href="@Url.Action("Delete", new {id = item.Id})">Delete</a>
<div class="btn btn-primary delete-confirm" style="display:none" data-delete-id="@item.Id">Confirm Delete</div>
</div>
</td>
</tr>
}

</table>

@section scripts{
<script type="text/javascript">
$(function () {
$("a.delete-link").click(function () {
var deleteLink = $(this);
deleteLink.hide();
var confirmButton = deleteLink.siblings(".delete-confirm");
confirmButton.show();

var cancelDelete = function () {
removeEvents();
showDeleteLink();
};

var deleteItem = function () {
removeEvents();
confirmButton.hide();
$.post(
'@Url.Action("Delete")',
AddAntiForgeryToken({ id: confirmButton.attr('data-delete-id') }))
.done(function () {
var parentRow = deleteLink.parents("tr:first");
parentRow.fadeOut('fast', function () {
parentRow.remove();
});
}).fail(function (data) {
alert("error");
});
return false;
};

var removeEvents = function () {
confirmButton.off("click", deleteItem);
$(document).on("click", cancelDelete);
$(document).off("keypress", onKeyPress);
};

var showDeleteLink = function () {
confirmButton.hide();
deleteLink.show();
};

var onKeyPress = function (e) {
//Cancel if escape key pressed
if (e.which == 27) {
cancelDelete();
}
};

confirmButton.on("click", deleteItem);
$(document).on("click", cancelDelete);
$(document).on("keypress", onKeyPress);

return false;
});

AddAntiForgeryToken = function (data) {
data.__RequestVerificationToken = $('input[name=__RequestVerificationToken]').val();
return data;
};
});
</script>

}

Hidden Web Essentials Feature –Check for best practices

Today, I came across an interesting and not very obvious feature of Web Essentials for Visual Studio 2013. This feature monitors the pages of your application when you are running the application in Visual Studio and scans for some best practice rules from the Web Dev Checklist.

Web Dev Checklist

The Web Dev Checklist is a list of rules to review before deploying any website / web application. It encapsulates what is generally considered best practices in web development. If you are not familiar with the Web Dev Checklist, I recommend that you review both the standard checklist and the ASP.NET specific checklist.

Web Essentials

Let’s take a look at how Web Essentials can automatically scan your application and warn you if you are violating some of the rules from the checklist.

First, ensure you have the latest version of the Web Essentials extension for Visual Studio 2013.

Now, open a web application project in Visual Studio and run the project in any browser. Navigate to a few different pages, then close the browser.

In Visual Studio, open the Error List by selecting View –> Error List in the main menu. If Web Essentials has found any issues, you will see them listed as Warnings and Messages in the Error List.

In this example, we can see that I have missed a few things that could help with Search Engine Optimization (SEO).

This is pretty helpful. Anytime you run the application, Web Essentials is sitting in the background analyzing the pages to ensure you are following certain best practices. It’s almost as if you get to pair programming with Mads Kristensen every day!

Not only do we get this helpful list of messages, but when you double click on a particular warning/message Web Essentials will actually help you fix the problem. When I double click the message regarding semantic meaning, I am taken to a website that explains the concept of semantic meaning. When I double click the warning regarding the missing <meta> tag, the meta tag is added to the page and all I need to do is fill in the description.

 

This feature is always running the background. All you need to do to take advantage of it is check the error list after you run your application. I know I will be making a habit of checking the error list from now on.

So you inherited an ASP.NET Web Forms application

If you like this post, you might be interested in my book Evolving Legacy ASP.NET Application: a by-example guide to updating a 12 year old ASP.NET application to use features of the modern ASP.NET stack

ASP.NET MVC has been around for a while now, so there is probably a good number of us who have only worked with MVC apps. Maybe you are one of those people and you have never touched a Web Forms app. You probably know what Web Forms is, but you have never actually worked on a large scale Web Forms project. Then one day, you start a new job. You open up that solution file on your first day and it hits you: BOOM! You’re now leading a team working on a big old messy Web Forms project.

Stay Calm

Take a deep breath and resist the urge to re-write the entire application in MVC. Why? Just for a refresher, read Joel Spolsky’s classic article: Things you should never do, Part 1. I still think there are some extreme cases where a re-write is the best option, but 98.3% of the time a re-write is a huge mistake.

Believe it or not, you are not alone in this whole Web Forms thing. The number of Web Forms projects in the wild still vastly outnumbers the number of MVC applications in the wild. And just because it’s a Web Forms project today, that doesn’t mean you can’t start using MVC for new features.

MVC and Web Forms in the same project?

That seems messy. Should we really promote such madness? Well, if you create a new Web project in Visual Studio 2013, you will notice that you no longer make the Web Forms vs MVC choice up front. There is now only 1 option, and that is ASP.NET Web Application.

Once you click OK, you are then prompted with an options dialog where you can in fact choose to create a project that contains both MVC and Web Forms.

This is part of the One ASP.NET concept that the ASP.NET team has been talking about for a while now. The message from the ASP.NET team is to stop thinking about it as ASP.NET Web Forms vs ASP.NET MVC vs ASP.NET Web API. Let’s just call it all ASP.NET and inside our ASP.NET projects we can include whatever pieces of ASP.NET we want to use.

Personally, I like this idea, because it makes me feel a lot better about that Web Forms ASP.NET project I just inherited.

Catching up with the rest of the world

Here are some relatively easy steps you can follow to get your project to the point where you can start leveraging some of the newer ASP.NET technology like MVC and Web API.

1. Upgrade to latest version of Visual Studio

Update to the latest version of Visual Studio that is available to you. As of writing this blog post, the latest version is 2013. Upgrading is usually straightforward. Simply open the solution in the latest version of Visual Studio and follow the steps in the Upgrade Wizard. You might need to upgrade some 3rd part components as part of this process. For example, if you are using Crystal Reports, you will need to install the latest Crystal Reports for Visual Studio.

2. Convert from Web Site Project to Web Application Project

If your application has its roots in a much older version of Visual Studio, you may be dealing with a Web Site Project. You can tell you are dealing with a Web Site Project by selecting the project and checking if a WEBSITE menu item appears on the Visual Studio menu. If so, I would strongly recommend you convert to a Web Application Project before proceeding to the next step. Follow these steps on MSDN.

3. Update all projects to the latest version of .NET

Right click on the Web Application project and click on Properties. Change the Target Framework to the latest version of .NET. Do this for each project in your solution.

4. Add MVC

This is traditionally a step that was very manual and rather clumsy (see here and here). Now thanks to Nuget and updates to Visual Studio, we can do this with very minimal manual changes to our application.

Start by adding the ASP.NET MVC libraries using Nuget. Right click on the Web Application Project and select Manage Nuget Packages. Select the Online option on the left and search for ASP.NET MVC. Click Install.

Alternatively, open the Package Manager Console and enter the following command:

Install-Package Microsoft.AspNet.MVC

In previous versions of Visual Studio, you needed to add a special Project Type GUID to the project file before Visual Studio would allow you to add MVC Controllers and Areas to the project. If you are using Visual Studio 2013 or Visual Studio 2012 Update 4, then this is no longer necessary.

To get started with MVC in an existing Web Forms application, I strongly recommend using an MVC Area.aspx) . This will help by keeping the controllers, models and views in a separate folder and also isolate changes to your web.config. To add an Area, right click on your web application project and select Add –> Area.

Give your area a Name, and Visual Studio will add an Areas folder containing a subfolder with the name you specified for your area. The subfolder will contain 3 sub-folders: Controllers, Models, and Views. You will notice a web.config file under the Views folder. This contains the configuration necessary for the MVC View engine and keeps us from needing to change the root application’s web.config.

Now you can add a Controller by right clicking the Controllers and selecting Add –> Controller. Select the empty template and provide a name for your controller.

Right click the return View(); section of the generated Index controller method and select Add View.

You now have a fully functioning MVC area in your existing Web Forms application. The last step is to add some startup logic to ensure that MVC area is properly registered. In the Application_Startup method of your Global.asax file, add the following line:

AreaRegistration.RegisterAllAreas();

Now run the application and navigate to your new MVC view by adding AreaName/ControllerName/Index to the end of the root URL for your application. Both your old Web Forms pages and your new MVC views should work. Magic!

This represents the absolute minimum amount of change needed in your Web Forms application before you can start using the latest version of MVC (or Web API). To start using more advanced MVC features you will also need to configure Routing.aspx), Bundling and Filtering.aspx).

If you like this post, you might be interested in my book Evolving Legacy ASP.NET Application: a by-example guide to updating a 12 year old ASP.NET application to use features of the modern ASP.NET stack

Minifying your HTML

As we have come to expect every week or two, a new version of Web Essentials for Visual Studio 2013 shipped on December 15th. From the Change Log, I noticed 2 new features: HTML File Minification and HTML File Bundles.

HTML File Minification

Minification is a common strategy used to reduce the size of source code files by removing any unnecessary characters. It is very common with JavaScript and CSS files and goes a long way in improving the performance of your website. For example, the minified version of jQuery is 92KB while the non-minified version is 268KB. A smaller file is better because the client will get it faster and you will require less bandwidth on your web server.

Minification is less common in html files, but the strategy still applies. With the latest version of Web Essentials, you can easily enable minification on your static HTML files. Right click on any HTML file in your project and select Web Essentials –> Minify HTML file(s).

 

You will notice a *.min.html file is added to your project.

This is the minified version of the original HTML file. It will appear exactly the same when viewed in a browser, but the source is compacted to be as small (and un-readable) as possible. If you make a change to the original file, the minified file will be updated automatically.

In this example, the minified HTML file was 33.3% smaller than the original file (4KB vs 6KB). Your mileage will vary, but I do see this as being useful in certain situations. One very good example would be SPA frameworks like Drundal that use html fragments to implement views. These applications could see a significant performance improvement by minifying all their view definitions.

To take advantage of the smaller file size, make sure any links to this file are referencing the minified version instead of the original version.

HTML File Bundles

HTML File Bundles takes the optimization one step further by allowing you to combine the contents of several HTML files into a single bundled (and minified file). While not overly useful when serving out traditional HTML files, this can be a huge performance benefit when using some SPA frameworks. Now, instead of making individual requests to get a large number of small files that make up your view or views, you can make a single request to get the contents of all the files. This is a similar concept to CSS and JS bundles in MVC.

To create an HTML File Bundle, select a set of HTML files in the Solution Explorer. Right click and select Web Essentials –> Create HTML bundle file.

 

You will be prompted to give the file bundle a name, then a few new files will be created (I entered ‘PageBundle’). Web Essentials will create 3 new files: A BundleName.html.bundle file that will contain the list of files contained in this bundle, a BundleName.html file that contains the contents of all the files you selected to be part of this bundle, and a BundleName.min.html file that contains a minified version of the BundleName.html file.

Summary

Download the latest version of Web Essentials for Visual Studio 2013 and give HTML Minification a try. How much smaller are your HTML files? Do you see a use for HTML file bundles in your applications?