Day 14: Bootstrap Alerts and MVC Framework TempData

This is an installment in a 30 day series on Bootstrap and the MVC Framework. To see more, check out Day 0 for an index.


This post is dedicated to the memory of my Grandmother, Marianne Chambers, who passed away June 14, 2014 with her two of her daughters at her side. She was a great woman who survived the passing of her husband and the early loss of a son, my father.


Something may go wrong, or it may go right. It may go smooth or go bump in the night. And, at various times, your application will want to let the user know about it. Bootstrap has a component called an Alert that works quite nicely for these types of information.

image

Likewise, the MVC Framework has a great place where we can store these messages without having to worry about postbacks, short term storage or the like. Pairing these two features up makes a great way to relay information to the user.

A Few More Helpers

Add another class file to your project in the Helpers namespace, and drop in the following code:

public class Alert
{
    public const string TempDataKey = "TempDataAlerts";

    public string AlertStyle { get; set; }
    public string Message { get; set; }
    public bool Dismissable { get; set; }
}

public static class AlertStyles
{
    public const string Success = "success";
    public const string Information = "info";
    public const string Warning = "warning";
    public const string Danger = "danger";
}
These classes give us some constants to help render our Bootstrap alerts, as well as a class to help store and pass data around. ## Base Controller – _Almost_ A Best Practice One of the first things you will likely do on any MVC project is to start with a new base controller that you will inherit from instead of the built-in Controller that ships with the framework. While that may seem like a weird suggestion coming from a guy who likes the YAGNI principle, I’ve never worked on a project that didn’t have a base controller, end up with one, or at least couldn’t have used one.  There will be valid cases where you won’t need one, and likely several cases where multiple base controllers will be required, so it’s debatable as to whether or not it should be a rule. This part is a best practice, however: don’t let your base classes get “fat”, loaded with code you’re not using 90% of the time. At any rate, if you choose to use them or not, for this project ours will look like this:
public class BaseController : Controller
{
    public void Success(string message, bool dismissable = false)
    {
        AddAlert(AlertStyles.Success, message, dismissable);
    }

    public void Information(string message, bool dismissable = false)
    {
        AddAlert(AlertStyles.Information, message, dismissable);
    }

    public void Warning(string message, bool dismissable = false)
    {
        AddAlert(AlertStyles.Warning, message, dismissable);
    }

    public void Danger(string message, bool dismissable = false)
    {
        AddAlert(AlertStyles.Danger, message, dismissable);
    }

    private void AddAlert(string alertStyle, string message, bool dismissable)
    {
        var alerts = TempData.ContainsKey(Alert.TempDataKey)
            ? (List<Alert>)TempData[Alert.TempDataKey]
            : new List<Alert>();

        alerts.Add(new Alert
        {
            AlertStyle = alertStyle,
            Message = message,
            Dismissable = dismissable
        });

        TempData[Alert.TempDataKey] = alerts;
    }

}
These methods are going to help us record and render alerts from our controller and into our views.  There are four pretty similar calls going on there that keep the helper strings away from our controllers.  The AddAlert method takes care of fetching or creating a list of alerts. We’re using TempData here for storage which is good for the next _completed_ request from the server to the same client. That could be the current request, should we complete execution and render a view, or that could be the immediately _next_ request, should we decide to redirect the user. Using a list of Alerts gives us the ability to add more than one type of alert, or several instances of alerts to the page at once. If you consider things like ActionFilters (those are coming) that have an opportunity to interact with the execution pipeline, you won’t ever know exactly what parts of your application might be trying to signal something to the user. **Note**: I got the idea for this approach through working with [Eric Hexter](https://twitter.com/ehexter) on the [Twitter.Bootstrap.Mvc](https://github.com/erichexter/twitter.bootstrap.mvc) project. In that version, Eric’s implementation allowed for one message per alert type, but it was definitely what got the ball rolling for me on this one. ## Updates to PersonController Start by changing the declaration to inherit from our spanky new base class.
public class PersonController : BaseController
Then, update your create method to use the new methods we’ve added.
[HttpPost]
public ActionResult Create(Person person)
{
    if (ModelState.IsValid)
    {
        _people.Add(person);
        Success(string.Format("<b>{0}</b> was successfully added to the database.", person.FirstName), true);
        return RedirectToAction("Index");
    }
    Danger("Looks like something went wrong. Please check your form.");
    return View(person);
}

We’ve made it super easy to store various alerts which will hang around in memory until we complete a request. In the case of the happy path above, the Success message hangs around on the server until the client requests the redirected content.  For the Danger message on the sad path, the view is immediately returned and the TempData is cleared.

Showing our Alerts

While we could just put all the info we need into the layout, we can keep our code cleaner by using a partial view to render the alerts. Under Views\Shared, add a new partial view called _Alerts.cshtml and put in the following code:

@{
var alerts = TempData.ContainsKey(Alert.TempDataKey)
? (List<Alert>)TempData[Alert.TempDataKey]
: new List<Alert>();

<span class="kwrd">if</span> (alerts.Any())
{
    &lt;hr/&gt;
}

<span class="kwrd">foreach</span> (var alert <span class="kwrd">in</span> alerts)
{
    var dismissableClass = alert.Dismissable ? <span class="str">"alert-dismissable"</span> : <span class="kwrd">null</span>;
    &lt;div <span class="kwrd">class</span>=<span class="str">"alert alert-@alert.AlertStyle @dismissableClass"</span>&gt;
        @<span class="kwrd">if</span> (alert.Dismissable)
        {
            &lt;button type=<span class="str">"button"</span> <span class="kwrd">class</span>=<span class="str">"close"</span> data-dismiss=<span class="str">"alert"</span> aria-hidden=<span class="str">"true"</span>&gt;&amp;times;&lt;/button&gt;
        }
        @Html.Raw(alert.Message)
    &lt;/div&gt;
}

}

We grab the alerts out of the TempData (if they exist) and then loop through each one, rendering them in the order they were added. If they had the dismissable flag set to true, we also render the appropriate Bootstrap elements and styles to make the alert go away on command.

Now update your _Layout.cshtml to include the call to render the partial view. Your container with the call to RenderBody() should now look like this:

<div class=“container body-content”>
@{ Html.RenderPartial(“_Alerts”); }
@RenderBody()
<hr />
<footer>
<p>&copy; @DateTime.Now.Year - My ASP.NET Application</p>
</footer>
</div>

And now, after you add a new person to the list, you’ll see a nicely formatted, dismissable alert at the top of the page.

image

Next Steps

We’ve been jumping around a bit and starting to form a few ideas about how the Asp.Net MVC Framework and Bootstrap can work together, but perhaps it’s time to look at a few of the basics that are already in use with the default template.