Running ASP.NET applications on Windows 7 machines

You might get a weird error when you publish your .NET site to a Windows 7 machine:

HTTP Error 500.19 - Internal Server Error
The requested page cannot be accessed because the related configuration data for the page is invalid.

Config Error This configuration section cannot be used at this path. This happens when the section is locked at a parent level. Locking is either by default (overrideModeDefault="Deny"), or set explicitly by a location tag with overrideMode="Deny" or the legacy allowOverride="false".  

The fix for this requires a change to applicationHost.config, located at:

%windir%\system32\inetsrv\config\

Change the following section overrideModeDefault values from "Deny" to "Allow" for the system.webServer section in configSections:

<section name="**handlers**" overrideModeDefault="Deny" /> 
<section name="**modules**" allowDefinition="MachineToApplication" overrideModeDefault="Deny" />

You might also get the following 404 error:

The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map.

Module StaticFileModule
Notification ExecuteRequestHandler
Handler StaticFile
Error Code 0x80070032

You will get this error if your IIS isn't configured to run ASP.NET applications. Go to Control Panel > Programs > Turn Windows features on or off > Internet Information Services > World Wide Web Services > Application Development Features and select "ASP.NET" (which will automatically select all required dependencies).

You might then get this error:

Configuration Error 
Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately. 

Parser Error Message: Unrecognized attribute 'targetFramework'. Note that attribute names are case-sensitive.

You will get this error if your website is in .NET 4.0 but the app pool that your website is running under is targeting .NET 2.0. To fix it, go to IIS Manager > Application Pools and select your website's app pool (probably the DefaultAppPool). Click on "Basic Settings" in the "Actions" window to the right and select the right version in the ".NET Framework version" dropdown.

Finally, you mighet get this error:

Handler "PageHandlerFactory-Integrated" has a bad module "ManagedPipelineHandler" in its module list

This can happen if ASP.NET 4.0 installatoin wasn't registered correctly; you can fix it by running the following command from the cmd prompt:

%windir%\Microsoft.NET\Framework\v[version number]\aspnet_regiis.exe -i

You should finally see your website.

Navisphere: Flexible menu creation framework for ASP.NET MVC

I talked about Navisphere a menu-creation framework for ASP.NET MVC in a previous article. I finally got around to uploading the source.

View Navisphere on GitHub

Creating charts in .NET

I think it's safe to say that most people prefer seeing summaries in charts instead of having to slog through rows and columns in an Excel spreadsheet. There are many frameworks out there to help you create charts in your .NET applications. Microsoft released a chart control at the end of 2008 that allows you to create many kind of charts1. Best of all, the chart control is completely free for you to use in any way you want.

Let's see how easy it is to create a chart.

Most Populated Cities In The World

Installations

Before you can start using the chart control, you need to install:

  1. Microsoft Chart Controls for Microsoft .NET 3.5
  2. Microsoft Chart Controls Add-on for Microsoft Visual Studio 20082

Microsoft also offers samples and documentation, which you can download at:

  1. Microsoft Chart Controls Samples
  2. Microsoft Chart Controls Documentation

Getting started

The first step is to setup the data points. You can do it programmatically; for example, you can (and often will) get the data from a database. For the sake of simplicity, we will define static data points in this article:

<asp:Chart ID="MostPopulatedCitiesChart" Height="300" Width="800" runat="server">
    <Series>
        <asp:Series 
            Name="Cities" 
            ChartType="Column" 
            ChartArea="MainChartArea" 
            YValueType="Int32" >
            <Points>
                <asp:DataPoint AxisLabel="Shanghai" YValues="7174" />
                <asp:DataPoint AxisLabel="Mumbai" YValues="22937" />
                <asp:DataPoint AxisLabel="Karachi" YValues="3683" />
                <asp:DataPoint AxisLabel="Delhi" YValues="29149" />
                <asp:DataPoint AxisLabel="Istanbul" YValues="6211" />
                <asp:DataPoint AxisLabel="São Paulo" YValues="7247" />
                <asp:DataPoint AxisLabel="Moscow" YValues="9722" />
                <asp:DataPoint AxisLabel="Seoul" YValues="17288" />
                <asp:DataPoint AxisLabel="Beijing" YValues="7400" />
                <asp:DataPoint AxisLabel="Mexico City" YValues="5954" />
            </Points>
        </asp:Series>
    </Series>
    <ChartAreas>
        <asp:ChartArea Name="MainChartArea" />
    </ChartAreas>
</asp:Chart>

That's all the "code" you need to write to show the chart:

Unformatted Chart

But it doesn't look very good. Let's make some formatting changes.

  1. Change the column colors and add gradients to something that's a little more pleasing.
  2. Add background gradients to the chart area.
  3. Lighten the gridlines.
  4. Add a title.
  5. Add labels to the axes.
  6. Show all column labels (via Interval="1")

What if you wanted to make it 3D? No big deal! Inside your chart area (""), add the following line:

<Area3DStyle Enable3D="true" />

And it's as simple as that!

3D Chart


  1. point, line, bar, doughnut, pie, circular, range, area, column, etc. 

  2. though it says 2008, it will work for 2010, as well. 

Framework for creating flexible menus

Background

Navigation is a common component of almost every web application. You show a bunch of links somewhere on your site to allow your user to easily get from one section of the application to another. If your application is complicated, the business rules surrounding the navigation are likely also complicated. For example, only a regular user can see this link while an administrator can see that link while everyone can see some other link, and, oh, there is this one link that should show up if the current context satisfied some predicate.

I had to deal with complicated navigation in two different applications, recently, and I absolutely hated having to write a long chain of if-else statements. So I spent some time creating a framework that allows me to easily configure an application's menus and all the business rules surrounding the display, availability, and execution of each menu item.

The framework, dubbed Navisphere, is built for ASP .NET MVC in mind, but it can pretty easily be extended to regular .NET web applications, as well.

Features

There are three things about a menu item that might vary from user to user, all of which Navisphere handles:

  1. What to display? Example: "Request Something" to regular users vs. "Order Something" to admins.
  2. How to execute it? Example: "Home" goes to one page for regular users vs. another page for admins.
  3. Who can see it? Example: Admin link is available to admins and nobody else.

And, of course, the display, execution, and availability of a menu item can also be context-sensitive (i.e., dependent on something other than roles).

Usage

The idea is to be able to write something like the following on each page load to get a list of menu items that you have to show to the user:

var menu = menuCreator.CreateFor(myContext);

Setting up the menu

Our application's menu has three items with the following business rules:

Menu Item 1
    - Text = "Home" for everyone
    - Is available to everyone 
    - Goes to admin/index for administrators and home/index for regular users

Menu Item 2 
    - Text = "Edit" for everyone 
    - Is available to administrators 
    - Goes to admin/edit for everyone 

Menu Item 3
    - Text = "Manage User" for administrator and "Manage My Profile" for user
    - Is available to everyone 
    - Goes to user/edit for everyone 

Let's setup the menu with Navisphere:

    MenuCreator
        .Setup(item => item 
            .IsShownTo.Everyone.As("Home")
            .IsAvailableTo.Everyone
            .IsExecutedBy.Roles("Administrator").Via("index", "admin")
            .IsExecutedBy.Roles("Regular").Via("index", "home"))

        .Setup(item => item
            .IsShownTo.Everyone.As("Edit")
            .IsAvailableTo.Roles("Administrator")
            .IsExecutedBy.Everyone.Via("edit", "admin"))

        .Setup(item => item
            .IsShownTo.Roles("Administrator").As("Manage User")
            .IsShownTo.Roles("Regular").As("Manage My Profile")
            .IsAvailableTo.Everyone
            .IsExecutedBy.Everyone.Via("edit", "user"));

And, to display the menu:

<ul>
    <% foreach(var link in MenuBoostrapper.Menu) { %>
        <li>
            <%= Html.ActionLink(
                        link.DisplayText, 
                        link.Action, 
                        link.Controller, 
                        null, 
                        null) %>
        </li>
    <% } %> 
</ul>

Where MenuBootstrapper is:

public static class MenuBootstrapper
{
    private static readonly IMenuCreator<HttpContext> _menuCreator;

    public static IMenu Menu
    {
        get { return _menuCreator.CreateFor(HttpContext.Current); }
    }

    static MenuBootstrapper()
    {
        // Setup the _menuCreator here.
    }
}

Conclusion

Except in simple websites, navigation almost always ends up getting a little (or a lot) complicated. Instead of littering your code with a bunch of if or switch statements, a far better option is to create a small framework once that will allow you to setup your menus according to your business rules in a way that developers can understand and modify easily.

The framework will be available for download soon.

OpenID and ASP .NET MVC

OpenID is a centralized membership mechanism. You register at one site and use those credentials with all other sites that you want to be a member of. This means that you have only one username and password set to memorize and, more importantly, that password is stored at only one location. When you want to log into a site that is enabled with OpenID authentication, you're forwarded to your OpenID provider. When you login, you are redirected back to the original site with your unique authorization token.

There are a lot of OpenID providers out there, including Google, Yahoo!, and Flickr. If you don't want to use one of the available providers, you can always roll your own OpenID provider.

Setting up your website for OpenID authentication is typically super-easy.

OpenID frameworks for .NET

There are a couple of different OpenID frameworks for .NET, but the one with the most active development is DotNetOpenAuth. On top of providing OpenID support for both the 1.x and 2.0 versions, DotNetOpenAuth also implements OAuth, which is a protocol for secure authorization. DotNetOpenAuth supports OpenID development in ASP, classic ASP .NET web applications, as well as ASP .NET MVC websites.

In this article, we're going to talk about how to setup OpenID authentication in your ASP .NET MVC website. Our process will be as follows:

  1. When users want to login, we provide a way for the users to select the URL for their OpenID provider.
  2. We redirect the users to the provider for authentication.
  3. If login failed for whatever reason, we let the user know.
  4. Otherwise, we check to see if this is the first time user is logging into our site.
  5. If it is, we register the user and redirect the user to select his or her display name.
  6. We update last login date for the user -- after they selected their display name in case of registration.

Login ViewPage

Our login view page is fairly simple: it includes a textbox for the user to enter the OpenID provider url. There are quite a few javascript libraries out there that make this a one-click process. Check out ID Selector.

<h2>Login with OpenID</h2>

<% Html.BeginForm("Authenticate", "Login"); %>
    <fieldset title="Login via OpenID">
        <% Html.RenderPartial("ErrorControl"); %>
        <p>
            <label for="openIdIdentifier">
                Manually enter your OpenID URL: </label>
            <%= Html.TextBox("openIdIdentifier", null, new { @class = "openId" }) %>
            <input type="submit" value="Login" />
        </p>
    </fieldset>
<% Html.EndForm(); %>

Authenticate via OpenID

Once the Login button is clicked, we get taken to the Authenticate action, which looks like this:

public ActionResult Authenticate(string openIdIdentifier)
{
    var openId = new OpenIdRelyingParty();
    var response = openId.GetResponse();

    if (UserNeedsToLogin(response))
    {
        return AskUserToLogin(openIdIdentifier, openId);
    }

    return HandleAuthenticationResponse(response);
}

private bool UserNeedsToLogin(IAuthenticationResponse response)
{
    return response == null;
}

private ActionResult AskUserToLogin(string openIdIdentifier, OpenIdRelyingParty openId)
{
    var request = openId.CreateRequest(openIdIdentifier);

    return request.RedirectingResponse.AsActionResult();
}

private ActionResult HandleAuthenticationResponse(IAuthenticationResponse response)
{
    switch(response.Status)
    {
        case AuthenticationStatus.Authenticated:
            return HandleSuccessfulLogin(response);
        case AuthenticationStatus.Canceled:
            _context.ErrorMessage = "Login was cancelled at the provider.";
            break;
        case AuthenticationStatus.Failed:
            _context.ErrorMessage = "Login failed at the provider.";
            break;
        case AuthenticationStatus.SetupRequired:
            _context.ErrorMessage = "The provider requires setup.";
            break;
        default:
            _context.ErrorMessage = "Login failed.";
            break;
    }

    return View("Index");
}

Successful login

The code for successful login looks as expected given our requirements:

private ActionResult HandleSuccessfulLogin(IAuthenticationResponse response)
{
    var claimedIdentifier = response.ClaimedIdentifier;

    registerIfUserIsNotRegisteredYet(claimedIdentifier);
    currentUserIs(claimedIdentifier);

    if (_context.CurrentUser.HasYetToLogin)
    {
        return RedirectToAction("FirstTimeLogin");
    }

    currentUserIsLoggedIn();

    return View();
}

private void currentUserIsLoggedIn()
{
    _accountRepository.Login(_context.CurrentUser);
}

If it's the first time the user is logging in, we register the user with the identifier returned by the OpenID provider.

private void registerIfUserIsNotRegisteredYet(Identifier claimedIdentifier)
{
    if (_accountRepository.Fetch(claimedIdentifier) == null)
    {
        var regularRole = new string[] { "Regular" };

        var userToRegister = new Account(claimedIdentifier, regularRole)
        {
            Id = 0, 
            LastLoginAt = DateTime.MinValue, 
            Profile = new Profile { DisplayName = claimedIdentifier }
        };

        _accountRepository.Insert(userToRegister);
    }
}

Account implements IPrincipal, and Profile has only one property for now (DisplayName). (You can add any other properties that make sense to your application, like FirstName, LastName, Email, etc.)

Setting up the current user

We also need to let our application know who the current user is. I do that by setting a "CurrentUser" property on my "context" object:

private void currentUserIs(Identifier claimedIdentifier)
{
    var registeredUser = _accountRepository.Fetch(claimedIdentifier);

    _contextUser.CurrentUser = registeredUser;
}

If user is logging in for the first time, ask for required information

Normally, I use the username for both Identity.Name and DisplayName. But with OpenID, the identifiers can be long, bizarre, and useless, so we need the user to provide us a display name. When the user provides us with the display name, we update our repository with the information. Since we figure out whether or not the user has logged in before based on the last login date, we don't set it for first-time users until after the user has provided all the required information and we've updated our repository with the information. For all other users, we set the last login date as soon as the user has logged in.

[HttpGet]
public ActionResult FirstTimeLogin()
{
    return View();
}

[HttpPost]
public ActionResult FirstTimeLogin(string displayName)
{
    if (string.IsNullOrWhiteSpace(displayName))
    {
        ModelState.AddModelError("displayName", "Display name is required.");

        return View();
    }

    var userName = _context.CurrentUser.Identity.Name;

    _accountRepository.UpdateDisplayName(userName, displayName);

    currentUserIsLoggedIn();

    return RedirectToAction("Index", "Home");
}

Conclusion

Integrating OpenID with your ASP.NET MVC website feels more complicated than it really is. While we had to write a lot of code, none of it is particularly complicated or unintuitive. DotNetOpenAuth and ASP.NET MVC make it especially easy.

Validation and ASP .NET MVC

A common requirement for web applications is validation. Almost every action follows the same kind of pattern: if the data is invalid, inform the user of the errors and show them the form again. Otherwise, process the request and take them to another page. If you're using ASP .NET MVC, you will notice this kind of code all over the place:

public ActionResult SomeView()
{
    if (!ModelState.IsValid)
    {
        return View();
    }

    // Do the real processing here, and 
    // redirect to some other view when 
    // you're done.
}

We all know that duplication is the number one enemy of maintainable code. If there is some way to not have to type in the "ModelState.IsValid" part for 50+% of the methods, then we save ourselves a lot of coding and maintaining. If you think about it, while the validation itself is different from method to method, how to respond to the validation is not. Ideally, we would like to write something like this:

public ActionResult SomeView()
{
    // Do the real processing here, and 
    // redirect to some other view when 
    // you're done.
}

Fortunately, ASP .NET MVC makes it pretty easy to do this.

Prerequisites

  1. ASP .NET MVC
  2. C# 4.0 (for "dynamic")

Step 1: How to do validation on the parameters?

The first step is to figure out how to validate each of the parameters passed into the action. Since validation will be different for each parameter, this means that we have to call some method on some class to perform the actual validation.

public interface IValidator<T>
{
    void Validate(T item);
}

However, we also need a way to tell the controller when some field on the model has an error on it so that it can tell the user. The user might also want to show when the value of some field is valid (maybe draw a green border around the field):

public interface IValidator<T>
{
    void Validate(T item, 
        Action<IValidationError> notifyOnError, 
        Action<IValidationSuccess> notifyOnSuccess);
}

IValidationError and IValidationSuccess are what you would expect:

public interface IValidationResult
{   
    string PropertyName { get; }

    T PropertyValue<T>();
}

public interface IValidationSuccess : IValidationResult
{

}

public interface IValidationError : IValidationResult
{
    string ErrorMessage { get; }
}

Step 2: Does a parameter support validation?

The next step is to figure out whether or not a particular parameter supports validation. If so, then we need a way to get the validator for that parameter. This is pretty simple: we create an interface that all models which support validation will have to implement:

public interface IValidatable<T>
{
    T GetValidator();
}

Step 3: Where to send the user on error?

The next challenge is to figure out where to send the user if there is an error. Since where to send the user might be different for different actions, our controllers will implement a method that will give us the error view given a context:

public interface IValidatableController
{
    ViewResult ErrorViewGiven(ActionExecutingContext context);
}

Step 4: Hooking everything up

The idea is that every time an appropriate action happens, we iterate through all the parameters that are sent. If the parameters support validation, then we get the Validator for the parameter and call the Validate method on it. Once we're done with validating all Validatable parameters, we check to see if there were any errors. If there were errors, we perform the error operation. Otherwise, we continue to the actual method. ASP .NET MVC provides a way for us to hook into the execution of a controller action via the ActionFilterAttribute. The method we are interested in is the OnActionExecuting, which is called -- well -- just before the action is executed.

Steps to take:

  1. Check to see if the controller implements IValidatableController. If not, we have nothing to do.
  2. Setup the error handler, which will add errors via ModelState.AddModelError
  3. For each parameter in the action, find those that implement IValidatable
  4. Get the Validator for each of these parameters to perform the validation.
  5. If there are any validation errors, perform error action. Otherwise, do nothing.

The code:

public class ValidateAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!(filterContext.Controller is IValidatableController))
        {
            return;
        }

        var validatableController = filterContext.Controller as IValidatableController;

        Action<IValidationError> errorHandler = x => 
            filterContext.Controller.ViewData.ModelState
            .AddModelError(x.PropertyName, x.ErrorMessage);

        foreach(var parameter in filterContext.ActionParameters)
        {
            if (!shouldValidateParameter(parameter.Value))
            {
                continue;
            }

            dynamic validatable = parameter.Value;
            dynamic validator = validatable.GetValidator();

            validator.Validate(validatable, errorHandler, null);

            if (!filterContext.Controller.ViewData.ModelState.IsValid)
            {
                filterContext.Result = validatableController.ErrorViewGiven(filterContext);
            }
        }
    }

    private bool shouldValidateParameter(object parameter)
    {
        return parameter.GetType().GetInterfaces().Any(x =>
            x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IValidatable<>));
    }
}

Note the use of "dynamic" to get the validator. We need to declare dynamic variables because C# doesn't allow us to cast parameters to their generic types without knowing the actual types. Fortunately, per C# 4.0, we are able to declare variables as dynamic, which causes the code to be late-bound.

Lambda Expressions

Lambda expressions are a new construct in C# 3.0 that provide a more concise way of writing anonymous methods (which were introduced in C# 2.0). Lambda expressions are especially useful in LINQ statements but can be used any place anonymous methods are.

Continue reading "Lambda Expressions"

Three Ways to Catch Exceptions in ASP .NET

Before we get on with the article, a couple of quick announcements. Regular readers of this site know well my tendency to put this site through an obnoxious number of redesigns. Sometimes I feel like I'm in a never-ending design cycle, because I'm always tweaking something here or adding something there. Anyway, I once again found myself twitching to do a redesign. I hesitate to say that I got tired of the old ( well, current, as of this entry ) theme, because I still like it; however, it most definitely grew old. So: look for the new design soon — like over the weekend; definitely over next week. :-)

Moving on.

Catching Exceptions in a Method

public void DownloadPdf(string path)
{
 try
 {
  System.IO.StreamReader reader = System.IO.File.OpenText(path);
 }

catch (System.UnauthorizedAccessException ex) { // Hey, you don't have access to the file! }

catch (System.IO.FileNotFoundException ex) { // Hey, the file doesn't exist }

catch (Exception ex) { // Something bad happened } }

Catching Exceptions at the Page Level

protected override void OnError(EventArgs e)
{
 Exception exception = HttpContext.Current.Server.GetLastError();

// Inform the user about the exception, log it, and do whatever // else you want to do here. }

Catching Exceptions at the Application Level

// In global.asax
protected void Application_Error(object sender, EventArgs e)
{
 Exception ex = HttpContext.Current.Server.GetLastError();

// Do whatever with the exception here. }

You might notice that catching exceptions at the application level is remarkably similar to catching them at the page level. This is good — one less thing for us to have to remember. :-)

Clearing Errors

What if you want to have your application continue on its merry way, not stop dead in its tracks because of the exception? For example, suppose the user is trying to upload a file and your application throws an exception because the file is too big. It would be nice if your application lets the user to continue working instead of taking him to the jarringly-ugly yellow page of death error page?

This is what happens when you catch an exception (aka, method 1), so you don't need to do anything special. However, it's a pain to have to wrap every single method in a try...catch block. The way to clear exceptions/errors with the other two methods is with the Server class' handy ClearError method:

 // In global.asax
protected void Application_Error(object sender, EventArgs e)
{
 Exception ex = HttpContext.Current.Server.GetLastError();

// Do whatever with the exception here.

HttpContext.Current.Server.ClearError(); }

Conclusion

You should, at some point, trap all exceptions that occur in your application. At the very least, you should redirect the user to a custom error page. Not only are the default error pages produced by ASP .NET horrendously ugly, they're usually unhelpful to the end-user. Also, they reveal information about your code, which is bad from a security-viewpoint. ASP .NET provides 3 very easy ways to trap errors in an application.

My favorite method — well, my second favorite method — of catching exceptions is using the Global.asax's Application_Error method. ( My favorite way is to use HttpModules, which I'm going to talk about in a future article. )

1 of 2 pages  1 2 >

On the Side