OdeToCode IC Logo

ASP.NET MVC - Highlight Current Link

Monday, August 27, 2012 by K. Scott Allen

In an ASP.NET MVC application, there are many different solutions you might use to highlight the menu item for the current location.

Highlight current item

Here's one - a custom HTML helper for building menu items. The custom helper will detect if the link is a link to the current action, and if so the helper adds an additional CSS class to the link (currentMenuItem).

public static MvcHtmlString MenuLink(
this HtmlHelper helper,
string text, string action, string controller)
{
var routeData = helper.ViewContext.RouteData.Values;
var currentController = routeData["controller"];
var currentAction = routeData["action"];

if(String.Equals(action, currentAction as string,
StringComparison.OrdinalIgnoreCase)
&&
String.Equals(controller, currentController as string,
StringComparison.OrdinalIgnoreCase))

{
return helper.ActionLink(
text,action, controller, null,
new { @class="currentMenuItem"}
);
}
return helper.ActionLink(text, action, controller);
}

Use the helper when building a menu in your Layout view.

<li>@Html.MenuLink("Contact", "Contact", "Home")</li>

And don't forget to add some styles to make the current link appear differently from the other links.

ul#menu li a {
background: none;
color: #999;
padding: 5px;
border-radius: 15px;
text-decoration: none;
}

ul#menu li a.currentMenuItem {
background-color: black;
color: white;
}

Another variant would be for the helper check the current controller name only when deciding to mark a link as current.

Levels Of Abstraction In An MVC View

Thursday, August 16, 2012 by K. Scott Allen

Working on a dashboard I came across a view arranged like the following diagram:

bad dashboard

The scenario is simplified because there is more to do inside of one block than just @SomeOutput, but focus on the structure of the view. I needed to add some more behaviors to the dashboard using CSS and script code, but it only took a few minutes to achieve frustration. Sometimes the view would delegate to a partial view for a specific section of the dashboard, and sometimes the view would inline all the markup and code for a section. Then there was also the odd case of having one partial view responsible for two entire sections of the dashboard, which threw me off entirely. Being new to the code it took some time to figure out how the pieces worked together to produce the page. 

Before I started making my own changes, I did a little refactoring to structure the view like so ...

better dashboard

... and then development life was easier. The mental model of how to map from implementation to output was simplified, and I instantly knew where to go to make different changes.

There are a number of ways you could spin this story. You could argue how the original view violated the single responsibility principle since it was taking responsibility for providing the structure of the dashboard and rendering some of the details. I’d agree with this argument. You could also argue the original view violated the single level of abstraction principle, and I’d agree with that argument, too.

In the end I simply liked the solution better because it seemed simple and symmetrical. Not many people talk about the aesthetic qualities of balance and symmetry in code, but I think it is a sign of craftsmanship that can benefit software by making code easier to understand and maintain. I bet the dashboard changes again in 3 months, and hopefully the next person has an easier time making those changes.

A Troubleshooting Guide for Entity Framework Connections And Migrations

Wednesday, August 15, 2012 by K. Scott Allen

The Entity Framework DbContext class uses a convention over configuration approach to development. When everything is working correctly, you can generate and populate a database just by writing a little bit of code and running “enable-migrations” and “update-database” from the Package Manager Console window in Visual Studio. No XML mapping or configuration files are required, see EF Code-Based Migrations Walkthrough for more details.

When things do not work, the conventions are frustrating because they form an impenetrable fog of mystery. Of course, having everything explicitly configured isn’t always clearer or easier to troubleshoot, but here are some common problems I’ve observed with EF 4.1 – EF 5.0, and some steps you can take to avoid the problems.

Cannot Connect to a Database

A couple popular errors you might run across include:

“System.Data.ProviderIncompatibleException: An error occurred while getting provider information from the database”

And the timeless message:

“System.Data.SqlClient.SqlException: A network-related or instance-specific error occurred while establishing a connection to SQL Server.

These messages can happen at any stage, from enable-migrations, to update-database, to running the application. The key to getting past one of these messages is figuring out which database the framework is trying to reach, and then making that database available (or pointing the framework somewhere else).

The first step I would recommend is trying to determine what connection string the framework is using, because the exception doesn’t tell you the connection string, and the connection string can be controlled by a variety of conventions, configurations, and code.

To find out the connection string, I’d add some logging to a default constructor in my DbContext derived class.

public class DepartmentDb : DbContext 
{
public DepartmentDb()
{
Debug.Write(Database.Connection.ConnectionString);
}

public DbSet<Person> People { get; set; }
}

Run the application with the debugger and watch the Visual Studio Output window. Or, set a breakpoint and observe the ConnectionString property as you go somewhere in the application that tries to make a database connection.

Chances are you’ll see something like the following:

Data Source=.\SQLEXPRESS;Initial Catalog=SomeNamespace.DepartmentDb;Integrated Security=True;

When there is no other configuration or code in place, the Entity Framework will try to connect to the local SQL Server Express database (.\SQLEXPRESS). Visual Studio 2010 will install SQL Server Express by default, so if you are not establishing a connection you might have customized the installation, shut down SQL Server Express, or did one of a thousand other things you might possibly do to make the database unavailable (like change the network protocols). One way to see what SQL services are available on your machine is to go to the Package Manager Console in Visual Studio and execute the following command (also showing the output below):

PM> Get-Service | Where-Object {$_.Name -like '*SQL*'}

Status   Name               DisplayName                          
------   ----               -----------                          
Stopped  MSSQLFDLauncher    SQL Full-text Filter Daemon Launche...
Stopped  MSSQLSERVER        SQL Server (MSSQLSERVER)             
Stopped  SQLBrowser         SQL Server Browser                   
Stopped  SQLSERVERAGENT     SQL Server Agent (MSSQLSERVER)       
Running  SQLWriter          SQL Server VSS Writer                

In the above output you can see I do not have a default SQLEXPRESS instance available (it would list itself as MSSQL$SQLEXPRESS), but I do have a default SQL Server instance installed (MSSQLSERVER – but it is not running). I’d have to start the service and give the Entity Framework an explicit connection string for this scenario to work (see Controlling Connections below).

EF 5 and Visual Studio 2012

Visual Studio 2012 installs SQL Server LocalDb by default. LocalDb is the new SQL Express with some notable differences from SQL Express 2008. A LocalDb instance runs as a user process, requires a different connection string, and stores the system databases under your hidden AppData directory.

Since LocalDb is a user process and not a service, you won’t see it listed in the output of the Get-Service command above. You can, however, run SqlLocalDb.exe from the package manager console (or the command line) to see if LocalDb is installed.

PM> SqlLocalDb info
v11.0

If the executable isn’t found, chances are you do not have LocalDb installed. In the above output, I can see I have LocalDb v11.0 installed. EF 5 will use LocalDb if it doesn’t detect SQL Express running, so when you look at the Database.Connection.ConnectionString property in the constructor, like we did earlier, you might  see the following instead:

Data Source=(localdb)\v11.0;Initial Catalog=SomeNamespace.DepartmentDb;Integrated Security=True;

(localdb)\v11.0 is the LocalDb connection string, and if you are not connecting to LocalDb then you might need to reinstall (here is a link that will eventually take you to the MSI file).

Connection Factories

How does the framework know to use LocalDb instead of Express? It’s done through configuration. If you open your application’s config file, you should see the following inside:

<entityFramework>
<defaultConnectionFactory
type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory,
EntityFramework"
>
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
</entityFramework>

Using the LocalDbConnectionFactory means you’ll no longer try to connect to SQL Express by default. There is also a connection factory for SQL Compact. You’ll find this factory in your config file if you install the EF SQL Compact NuGet package.

Insufficient Permissions

Another common problem I’ve seen popping up when using Code First migrations is typically realized with one of the following exceptions:

System.Data.SqlClient.SqlException: Login failed for user ‘[Your account here]'.

... and ...

System.Data.SqlClient.SqlException (0x80131904): CREATE DATABASE permission denied in database 'master'.

These permission issues can be hard to fix. The first thing I’d do is add some debugging code to verify the connection string being used by the Entity Framework (the debugging code demonstrated earlier). Once you know the server the Entity Framework is trying to reach you should try to login to the server with a management tool (like SQL Management Studio, which also works with LocalDb), if you can. The problem is you might not be able to login with your account.

Even if you are an administrator on your local machine you might find yourself with limited privileges in your own, local SQL Server. One scenario where this can happen is when SQL Server or SQL Server Express is installed onto your machine by a different user, or you installed the software using a different account, or perhaps your machine was built from a cloned image file. As of SQL 2008, just being an administrator in Windows doesn’t make you a sysadmin in SQL Server.

To fix the permission issues you can try to login to the server using the sa account, but of course you must know the password and the sa account must be enabled. You can also try to login to your machine using the Windows account used for the software installation. Once logged in with high privileges you’ll need to add your Windows login to the list of SQL Server logins and (ideally) put yourself in the sysadmin server role

When all else fails, you can try to regain control of SQL Server by starting the server in single user mode (see Connect to SQL Server When System Administrators Are Locked Out). The SQL Express blog also published a script to automate this process (see How to take ownership of your local SQL Server), which should also work with SQL 2012. The nuclear option, if you don’t care about any of the local databases, is to uninstall and reinstall SQL Server.

Cannot Attach to Deleted MDF File

If you are using SQL LocalDb, don’t ever delete the physical .mdf and .log files for your database without going through the SQL Server Object Explorer in Visual Studio or in SQL Server Management Studio. If you delete the files only, you end up with an error like the following in a web application:

Cannot attach the file ‘…\App_Data\DepartmentDb.mdf' as database 'DepartmentDb'.

Or the following error in a desktop app:

SqlException: Cannot open database "DepartmentDb" requested by the login. The login failed.

In this case the database is still registered in LocalDb, so you’ll need to go in the Object Explorer and also delete the database here before SQL Server will recreate the files. 

SQL Server Object Explorer in VS2012

Controlling Connections

Explicitly controlling the connection string for the Entity Framework is easy. You can pass a connection string to the DbContext constructor, or you can pass the name of a connection string that resides in the application’s configuration file. For example, the following code will make sure the Entity Framework connects to the local SQL Server default instance and use a database named departments.

public class DepartmentDb : DbContext 
{
public DepartmentDb()
: base(@"data source=.;
initial catalog=departments;
integrated security=true"
)
{
}

public DbSet<Person> People { get; set; }
}

While the following would tell the framework to look for a connection string named departments in the config file:

public class DepartmentDb : DbContext 
{
public DepartmentDb() : base("departments")
{
}

public DbSet<Person> People { get; set; }
}

If the Entity Framework does not find a connection string named “departments” in you config file, it will assume you want a database named departments on the local SQL Express or LocalDb instances (depending on which connection factory is in place).

Finally, if you do not pass any hints to the DbContext constructor, it will also look for a connection string with the same name as your class (DepartmentDb) in the config file.

As you can see, there are lots of options the Entity Framework tries when establishing a connection. The goal of all this work is to make it easy for you to use databases, but when software is misconfigured or not installed correctly, all these options can also make troubleshooting a bit difficult.

Where Are We?

When troubleshooting connection problems with the Entity Framework the first step is to always figure out what server and database the framework is trying to use. If the problems are permission related, the next step is to find a way to make yourself a sysadmin on the server (or at least get yourself in the dbcreator role). If the problem is making a connection to a server instance that doesn’t exist, you can always explicitly configure a connection string for an existing instance of SQL Server.

If all else fails, use SQL Server Compact, as nearly anything you can do with Code-First Entity Framework will work the compact edition of SQL Server.

Configuration Tips For ASP.NET MVC 4 on a Windows Azure Website

Tuesday, August 7, 2012 by K. Scott Allen

The new Windows Azure Website feature is easy to use. You can deploy an application by publishing from  Visual Studio or by pushing code with git. There are a few extra configuration steps I’ve found useful.

Using HTTP PUT and DELETE with the ASP.NET WebAPI

Using PUT and DELETE with Azure (or IIS, or IIS Express for that matter) requires some extra configuration before the server will allow messages with these methods into the processing pipeline. By default, IIS will only allow GET, HEAD, POST, and DEBUG. The following configuration section goes inside of <system.webserver>, and will tell IIS to process PUT and DELETE, too.

Note: the final release version of ASP.NET MVC 4 will include this configuration in web.config by default when you create a new project*, but it is still handy for upgrades and to generally know why it exists.

<handlers>
<remove name="ExtensionlessUrl-Integrated-4.0" />
<add name="ExtensionlessUrl-Integrated-4.0"
path="*."
verb="GET,HEAD,POST,DEBUG,DELETE,PUT"
type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

The Usual HTML 5 Media Types

Before IIS will serve a static file it needs to know the media type associated with the file. Video and SVG files were refusing to work until I added the following (also in the <system.webserver> section of web.config):

<staticContent>
<remove fileExtension=".mp4"/>
<remove fileExtension=".ogv"/>
<remove fileExtension=".webm"/>
<remove fileExtension=".svg"/>
<mimeMap fileExtension=".mp4" mimeType="video/mp4" />
<mimeMap fileExtension=".ogv" mimeType="video/ogg" />
<mimeMap fileExtension=".webm" mimeType="video/webm" />
<mimeMap fileExtension=".svg" mimeType="image/svg+xml"/>
</staticContent>

The <remove> entries will allow the configuration to work even on local servers that already have the media types configured (you’ll have a runtime error if you add a duplicate entry, but there is no error if you remove an entry that doesn’t exist).

Automatic Migrations

Finally, if you are using Code First Entity Framework migrations you can have them execute automatically after a release push by adding  to the Web.Release.config file. Web.config transformations even work with git deployments to Azure.

<entityFramework>
<contexts xdt:Transform="Insert">
<context type="EmployeeApp.EmployeeDb, MvcApplication10">
<databaseInitializer
type="System.Data.Entity.MigrateDatabaseToLatestVersion`2[
[EmployeeApp.EmployeeDb,MvcApplication10],
[MvcApplication10.Migrations.Configuration, MvcApplication10]
], EntityFramework"
/>
</context>
</contexts>
</entityFramework>

Of course you’ll need to substitute your own DbContext and Configuration types as the generic type parameters to MigrateDatabaseToLatestVersion. See EF 4.3 Configuration File Settings for more details (yes, it works with EF 5.0, too).

* MVC 4 will also configure ExtensionlessUrlHandler-ISAPI-4.0_32bit and ExtensionlessUrlHandler-ISAPI-4.0_64bit.

MVC 4 Video Outtakes

Monday, July 30, 2012 by K. Scott Allen

I recently finished an ASP.NET MVC 4 course for Pluralsight.

Making a set of tech videos is not an easy job for me. Every video needs careful editing to remove moments of despair, frustration, and delusion. Not to mention the workplace hazards.

I put together 90 seconds of outtakes from the MVC 4 videos to share with you. I hope you can laugh at the painful parts (direct link):

Swinging on a Canvas

Thursday, July 26, 2012 by K. Scott Allen

verlet with JavaScriptBuilding on top of requestAnimationFrame from earlier this week, I put together a simple example of using basic verlet integration to simulate a swinging rope in an HTML 5 canvas. You can pull the source from github, or try the sample on jsFiddle.

It’s amazing what you can do just by adding numbers together in a certain fashion. To make things interesting, there is also an option to let the rope leave a trail of pixels behind as it swings, which can make for interesting patterns (as shown in the image in this post).

Evolution of the Entity Framework: Lesson 5

Wednesday, July 25, 2012 by K. Scott Allen

Imagine you are in control of a large company who specializes in building tools for developers. Your staff is full of developers with tool building expertise. They write lexers during lunch breaks and WYSIWYG designers on weekends.

Next, imagine someone asks you to select the perfect serialization format for your tools. Of course you’d pick XML, right? XML is easy to parse when you need to load data into your tool, and easy to create when your tool saves some output.  Building tools with XML is like having your cake and eating it, too.

XML cake

But wait, did anyone ask the customer if XML makes their job easier?

An Ocean of Angle Brackets

XML appears in everything from configuration files to form builders these days. In some scenarios XML is a good choice, but quite often developers have to read, write, and modify the XML created by tools, or we have to understand what a tool is producing, or we need to see the differences between two versions of the tool’s output to track down a bug in our software. None of these scenarios are pleasant to deal with. Tool vendors like to use XML because XML is convenient for the tools, but contrast this justification for XML against the design philosophy for Ruby put forth by Matz:

I hope to see Ruby help every programmer in the world to be productive, and to enjoy programming, and to be happy. That is the primary purpose of Ruby language.

When is the last time you felt productive and happy with XML?

Of course, the idea is to work only inside the tool and never look at the XML output. It’s easy to stay in a tool when a tool is a word processor, but developer tools are different.

Here are a few examples.

The first two versions of the Entity Framework used a visual designer to generate an .edmx file with all of the model metadata required for the Entity Framework to function. The .edmx file was an XML file. It was possible to do some work in the designer only to discover a build error during the next compiler run. A build error like the following:

Problem in Mapping Fragments starting at lines 6, 69: Non-Primary-Key column(s) CalendarID are being mapped in both fragments to different conceptual side properties - data inconsistency is possible because the corresponding conceptual side properties can be independently modified.

After you get past the initial shock of the foreign vocabulary being presented you’ll realize the error message is pointing you to lines of code inside the XML contents of the .edmx file. Woe to those who open the .edmx file with an XML editor and wade through the ocean of angle brackets. The entity data model inside the file requires more XML than you might expect if you’ve previously done any ORM mapping with XML files.

It was also possible, particularly in V1, to run into a scenario the entity data model designer didn’t support. To implement table-per-hierarchy inheritance, for example, required wading through several hundred lines of XML just to figure out the important bits that make the inheritance approach work.

Which leads us to the 5th and final lesson derived from the evolution of the Entity Framework:

Lesson 5: Have Empathy For Your Customer

When you sit down to design a software framework or tool, something you should keep in mind is the user experience. How will they interact with your software? How will they use your software to perform a job? What sort of jobs will the user need to do? Will they be happy, and productive, and enjoy programming?

There were a number of difficult aspects to the Entity Framework that all appear to derive from design decisions that benefited the Entity Framework instead of the customer. The non-standard connection strings, the lack of implicit lazy loading, the difficult API for working with object graphs, the visual designer that couldn’t scale up to model complex domains, and of course the mountains of XML, to name just a few.

In a future post we’ll take a more positive attitude and see how the more recent versions of the Entity Framework have addressed the 5 lessons we’ve looked at over this series of posts.