Day 21: Cleaning Up Filtering, the Layout & the Menu

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.

In software development we often talk about concepts like the Single Responsibility Principle. Web pages are often doing lots of things, so it’s hard to say that it should always apply when we’re building our views. But, in the spirit of Martin Fowler’s take on it, I would argue that our _Layout.cshtml is starting to get a lot of reasons as to why it might change, and for that reason, we’re going to split out the menu.

Extracting the Menu

In your Views\Shared folder add another partial called _MenuPartial.cshtml and paste in the following code.

@using SimpleSite.Models
<ul class="nav navbar-nav">
    <li>@Html.ActionLink("Home", "Index", "Home")</li>
    <li>@Html.ActionLink("About", "About", "Home")</li>
    <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
    <li>@Html.ActionLink("My Peeps", "Index", "Simple")</li>

    @if (ViewBag.Notifications != null)
    {
        foreach (NotificationViewModel notification in ViewBag.Notifications)
        {
            <li>
                <a href="#">
                    @notification.NotificationType
                    <span class="badge badge-@notification.BadgeClass">
                        @notification.Count
                    </span>
                </a>
            </li>
        }
    }
</ul>
If you flip back to our _Layout view, you’ll see that this is very close to what we had there. I’ve made two important changes: 1. I’ve added a link to our SimpleController in the menu. 2. I’m checking to make sure there is data in the ViewBag before accessing the dynamic property. This will prevent errors should there be no notifications for the users. If you do #1 without #2 above, you will most definitely get errors because the only place that has notifications injected is in the Index action on the Home controller. With those bits in place, be sure to pop back into your _Layout, and update the navbar where we had previously added the code for notifications. It should now only include a call to render our _MenuPartial and the _LoginPartial.
<div class="navbar-collapse collapse">
    @Html.Partial("_MenuPartial")
    @Html.Partial("_LoginPartial")
</div>

If you run the site at this point you won’t get any errors, but you’ll only see the notifications on the home page. Let’s address that.

Globally Registering an Action Filter

We’re now going to set it up so that our NotificationFilter is executed on every request. I just ask that you remember that this is a demo, and that there are a few caveats you should be aware of.

During application startup (checkout your global.asax in the root of the site) you’ll notice a call to FilterConfig.RegisterGlobalFilters. There is no magic here. There’s a static method on a class located in your App_Start folder that helps to keep that global.asax nice and tidy. A GlobalFilterCollection is passed in and we can then add to it.

In previous versions of the MVC template, this wasn’t around, so most folks ended up either dropping in a ton of lifting into Application_Start or otherwise coming up with a comparable solution to the above. Now, the class that does the FilterConfig does the FilterConfig. Kinda like that whole Single Responsibility Principle again, eh?

Update FilterConfig (which has the global error handling baked in already) to also include the registration of our filter:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new NotificationFilter());
}


Now, return to the Home Controller and remove the NotificationFilter attribute from the Index action.  It won’t really matter if you don’t (the Framework is smart enough to see that it’s already in play) but you might confuse the future version of yourself when you disable the global registration down the road and the filter keeps getting executed.

You’re all set!

Next Steps

One final step that you might want to consider in the clean up is to move your notification model to a separate DLL, but I’ll leave that as an exercise to the reader as it’s more of a “code” thing and less of an “MVC or Bootstrap” thing.

Next up, we’ll tackle user registration and membership.

Day 20: An ActionFilter to Inject Notifications

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.

Yesterday we added some good-looking notification badges to our site using our customized Bootstrap badges. Now we need to take care of this nonsense where we need to put the same code into _every single method and every single controller _that we write.

[image[5]](https://jcblogimages.blob.core.windows.net/img/2014/06/image51.png)

Yay for the badges, boo for the code. To get around this, we’ll explore one of many different ways we solve this problem of repeating ourselves by writing an action filter.

A Bit About the MVC Pipeline

There’s a lot going on behind the scenes in a web request, but thankfully much of it is abstracted away for most development tasks, and nearly all of it is abstracted away for the end user (could you imagine trying to explain to Mom or Dad how to manually resolve the IP address of domain name? Yikes!).

Sometimes you need to dive into the abstraction, and action filters are one area where this is the case. Remember back on day one of this series I broke down the request a little? And on day two I introduced some of the terminology? Well…if you’ve been following along, you can probably infer what an action filter might be up to: before or after executing an action on a controller you get to inspect, prod, poke and otherwise modify the content or even redirect the user as you see fit. From MSDN.aspx):

Action filters. These implement IActionFilter.aspx) and wrap the action method execution. The IActionFilter.aspx) interface declares two methods: OnActionExecuting.aspx) and OnActionExecuted.aspx).OnActionExecuting.aspx) runs before the action method. OnActionExecuted.aspx) runs after the action method and can perform additional processing, such as providing extra data to the action method, inspecting the return value, or canceling execution of the action method.

You can deny access, restrict availability of resources and execute arbitrary code. You even have access to internal parts of MVC, so your filter can be aware of the currently executing controller, action, and target view.

And that’s where we’re going to hook in: just before the view is rendered after the action method has run.

Adding the Filter

Add a folder to the root of your site called Filters (this isn’t convention, just a way to help keep you organized) and then add a class called NotificationFilter. Inherit from ActionFilterAttribute, and then override the OnActionExecuted method so that you can add your two cents to the request.  Your code will be nearly identical to what you put in the Home controller, except note now that the ViewBag property is actually accessed through the Controller property on your filterContext.

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
var context = new SiteDataContext();

var notifications = context.Notifications
    .GroupBy(n =&gt; n.NotificationType)
    .Select(g =&gt; <span class="kwrd">new</span> NotificationViewModel
    {
        Count = g.Count(),
        NotificationType = g.Key.ToString(),
        BadgeClass = NotificationType.Email == g.Key
            ? <span class="str">"success"</span>
            : <span class="str">"info"</span>
    });

filterContext.Controller.ViewBag.Notifications = notifications;

}

ActionFilterAttribute gives you four virtual methods for actions and results on executing and executed. You only have to implement the ones that suit your fancy.  Because it’s an attribute class, you can decorate your actions (or even your classes) with it and the MVC Framework will pick it up and execute it when the time is right.

Touch up the Controller

Now on your HomeController we can clean things up a fair bit. Remove almost all the code from the Index action and decorate it with your new attribute.

[NotificationFilter]
public ActionResult Index()
{
return View();
}

Much cleaner, eh? You can now run your site and you’ll get the same result as we had before, and the notifications will now appear anywhere you place that attribute. If you put it at the class level, all actions on the controller will have the filter applied.  Which means I should probably mention…

…Some Notes and Caveats

This is a pretty powerful deal, especially at the class level. Heck, you can even globally register your filter and have it execute on every request. Which is why I have to stress some pretty important bits:

  • If it’s always executing, then it’s always executing. Be mindful of decorating your classes as a rule or registering filters globally, especially if you have requests (AJAX) that maybe don’t need the filter.  Alternatively, design your filter in such a way that it knows when it should or shouldn’t run.
  • Lots-of-stuff-going-on doesn’t scale well. Use filters judiciously so that you’re not bogging your site down with unnecessary operations. Be quick in what you do so that you return quickly and keep your performance up. Use profiling if you’re not sure how fast your code is running.
  • In this example – and I can get away with it because it’s an example – I’m going to the database on each request. It may suit you well to do this, but consider alternate approaches (such as caches with timeouts and operations that invalidate them) so that you’re not making those hits all the time.

Next Steps

We still have a few things to clean up from Day 19, so we’ll keep working away at some housekeeping tasks tomorrow, working on our layout.

Day 19: Long-Running Notifications Using Badges and Entity Framework Code First

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.

We previously looked at using TempData to store alerts, which is great when what we are trying to alert the user to is a transient message that lives only for the next request. What about the scenario where we have long running notifications? Unread email? Outstanding actions the user must follow up on?

Today we’re going to bang out a solution here…in the interest of time and simplicity this will not be in line with best practices, but come back tomorrow for a discussion on how to get closer to them.

Rocking Out A Model

If we want a way to indicate that the user needs to take care of something, we need two pieces: some kind of UI to point it out – which we have with badges – and some place to store the data – which we’ll get with EF.  Right-click on your Models directory and add a new class, called Notification, and add the following code to it:

    public enum NotificationType
    {
        Registration,
        Email
    }

    public class Notification
    {
        public int NotificationId { get; set; }
        public string Title { get; set; }
        public NotificationType NotificationType { get; set; }
        public string Controller { get; set; }
        public string Action { get; set; }
    }
These are _just_ classes, but when we lean on Entity Framework, we get a database out of it as well. In the “code first” approach, we first write ourselves a class that represents the data, as we’ve done above. Next, we have to let EF know that we expect a storage mechanism for that data, namely, we create a data context and a DB set (representing a table) inside of another class. Add SiteDataContext as a class in your Models folder and add the following code to it:
    public class SiteDataContext : DbContext
    {
        public SiteDataContext() : base("DefaultConnection") { }

        public DbSet<Notification> Notifications { get; set; }
    }
There’s not much to it: DbSet represents a table and DbContext identifies this as a class that represents a connection to the database. If the DB doesn’t exist, EF creates it for us. We call the base class constructor with a string, which identifies the connection string to use in the web.config file, if present, or the name of the DB that will be created if it doesn’t. At this point, **build your project **using Shift+Ctrl+B or by pressing F6\. We need the app compiled to take advantage of tooling in Entity Framework. Now, go to the Package Manager Console (View –> Other Windows –> Package Manager Console) and type the following command:
Enable-Migrations -ContextTypeName SimpleSite.Models.SiteDataContext

You’ll need to make sure that the namespace and class name match what is specified above. This command generates a configuration file that has an empty Seed method (rather, it has some comments in it, but you can delete them).  This file can be used by Entity Framework as a way to do advanced configuration, set your own conventions for table naming, or, in our case, seeding the database with some test data.  Paste in the following code in the Seed method:

protected override void Seed(SimpleSite.Models.SiteDataContext context)
{
context.Notifications.AddOrUpdate(notification => notification.Title,
new Notification
{
Title = “John Smith was added to the system.”,
NotificationType = NotificationType.Registration
},
new Notification
{
Title = “Susan Peters was added to the system.”,
NotificationType = NotificationType.Registration
},
new Notification
{
Title = “Just an FYI on Thursday’s meeting”,
NotificationType = NotificationType.Email
});
}

AddOrUpdate is like an “upsert” method you can use to inject or update data in your DB.  It accepts a lambda expression that specifies how unique rows are identified, and a parameter array which is a list of objects you want to inject into the specified table.

Updating our Database

With support for the migrations in place, we want to create an initial version of the DB and apply it in our development environment. From the Package Manager Console, type these lines of code:

Add-Migration db-create

Update-Database

Have a look through the migration class that is generated. Pretty cool, eh? Although this is just a first stab at it, it really shows how you can customize the build up – or tear down – of you tables. It’s worth a whole book of content, though, so I’m not diving in for now! The call to Update-Database executes the Up() method on all outstanding migrations. Everything is tracked for you by EF in the database.

Okay, Here’s One Best Practice

One thing that I really like about MVC and EF is how easy it is to get data into your view using the entities of your database. One thing that I really hate about MVC and EF is how easy it is to get data into your view using the entities of your database. For reals. It’s great for demos and terrible for production.

Instead, use a view model…a way to decouple your view from your database completely. Get in this habit as early as you can, and then come back and thank me 6 months into the maintenance portion of your contract.

Add another class called NotificationViewModel and write in the following code:

public class NotificationViewModel
{
public int Count { get; set; }
public string NotificationType { get; set; }
public string BadgeClass { get; set; }
}

Rather than relying on the data in the database we’re going to use a projection of the data instead. This can help to shield our UI from changes in the model and eliminate the risk of excess DB access or over-exposing sensitive data. It also allows for other best practices we’ll cover in the days ahead.

Updating Our Controller

Update your Index() action to be the following:

public ActionResult Index()
{
var context = new SiteDataContext();

var notifications = context.Notifications
    .GroupBy(n =&gt; n.NotificationType)
    .Select(g =&gt; <span class="kwrd">new</span> NotificationViewModel
    {
        Count = g.Count(),
        NotificationType = g.Key.ToString(),
        BadgeClass = NotificationType.Email == g.Key
            ? <span class="str">"success"</span>
            : <span class="str">"info"</span>
    });

ViewBag.Notifications = notifications;

<span class="kwrd">return</span> View();

}

We’re getting the list of notifications out of the DB, grouping them by type, specifying the style class to use and counting them op.  We then set that information in the ViewBag, which is accessible from our views. Note that this approach only works for now in our Index method, and only on the HomeController. Don’t worry, we’ll take care of that tomorrow. Smile

Lighting up Notifications in the View

Find the UL element with the class “nav navbar-nav” that contains the LI elements that compose the menu (these are around line 26 for me). At the end of the LI elements, we’re going to inject a few more, so we iterate over the list of notifications that we popped into the ViewBag like so:

@foreach (NotificationViewModel notification in ViewBag.Notifications)
{
<li><a href=“#”>@notification.NotificationType <span class=“badge badge-@notification.BadgeClass>@notification.Count</span></a></li>
}

We’ve got some more work to do to fully get these working, but you will likely see the direction this is moving in by now, and users will see that something needs to be done about all those…notifications.

image

Next Steps

Well, as I said we’ve got some clean up to do to get a little closer to best practices. Our models are in our web site project and unable to be reused. We have to put code in each and every single action on every controller where we would want to see notifications. Our layout is getting polluted with additional code. There’s no way to resolve notifications. We’re in bad shape!

Check back tomorrow so that we can resolve some of the low hanging fruit and discuss what remains to get some of this train on the rails.

Day ?: A Break for Family

This past week I attended the funeral of my Grandma and, as such, put this series on hold. I am back from Northern Saskatchewan and I’ll be resuming the daily posts starting tomorrow.

In turn, we’ll be wrapping up this adventure on July 4, so we’ll go out with a bang.

A little later in the series we’re going to be working with a real-time pub/sub library called SignalR. It would be a good thing to do to read up on it a little, and perhaps even run through some of the exercises. I won’t be heavily covering it as it’s not the focus of this work, but we will use it to bring some interesting functionality into play.

While I’ve enjoyed the break and the chance to spend some time with family, I’m eager to wrap up the posts and finish off this work.

Happy weekend.

Day 18: Customizing and Rendering Bootstrap Badges

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.

Bootstrap comes with some great styles and base starting points, but it’s not meant to be the be-all and end-all of design. There are often times when a simple CSS tweak can make your site stand apart from others.

Using the Built-In Badge

Badges are pretty easy to render. You mark up a SPAN with the “badge” class and you’re off to the races.

<a href=”#”>Registrations <span class=”badge”>19</span></a>

That ends up looking something like this:

image

And if you put it in a navbar, it looks like this:

image

So it’s an easy way to convey that the user has something that needs to be done, check unread messages, complete some kind of task or, say, approve People registrations. But the white-on-grey is a little bland.

Non-Intrusive Customizations

I wouldn’t recommend modifying the base Bootstrap.css class itself. If there are incremental updates you would lose the ability to update your project without losing changes, save using a merge tool and sorting out the diff on your own. You would likely be better served to extend Bootstrap with LESS or SASS if that suits your fancy, but there is an easier approach as well that’s as old as CSS itself: just add another stylesheet to your project. Sometimes low-tech is the easiest answer.

What we’d like to do is to get a palette of options like so:

image

Let’s start by adding a new CSS file to the project. Expand the Content folder in your solution and you should see bootstrap.css. Right-click on the Content folder, and add a new Style Sheet called “bootstrap.custom.css”, then paste in the following code:

.badge-danger {
background-color: #d43f3a;
}

.badge-warning {
background-color: #d58512;
}

.badge-success {
background-color: #398439;
}

.badge-info {
background-color: #269abc;
}

.badge-inverse {
background-color: #333333;
}

These are just classes styled after the button classes, using the same solid colors for the background. You could event go a step further and introduce hover states (like buttons) or borders (like for labels) depending on your fancy.

Next, we need to get our site aware of this file. If you’re a traditional web developer you might be inclined to update your template or master page and add some markup to include the CSS, but we have a different approach in today’s web: update our bundle.

Including the File

Navigate to the App_Start folder in your solution and open the BundleConfig.cs file. Update the bundle that includes the bootstrap.css file to the following:

bundles.Add(new StyleBundle(“~/Content/css”).Include(
“~/Content/bootstrap.css”,
“~/Content/bootstrap.custom.css”,
“~/Content/site.css”));

If you’ve already got the site running, you’ll want to recompile at this point. You won’t need to in order to make changes to your style sheet, but BundleConfig is only ever run once at startup. Bundles have built-in cachebusters that prevent your CSS from getting stale while you edit it, but you’ll need to do that rebuild just once.

Badge Up Your Site!

Now you are free to add something like the following to any of your pages:

<p>
<a href=”#”>Registrations <span class=”badge”>19</span></a>
</p>

One cool but likely expected aspect is that if you put a badge inside of an A tag, as I have above here, the badge is also clickable, so keep that in mind as you’re hacking together your markup.

Next Steps

Next up we will come up with a practical way to leverage these badges in our site and display them in the navbar.

Day 17: Free Training For All the Peoples!

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.

I hope you’re enjoying the series so far, I’m certainly enjoying creating it. And you know what, blogs are great, but watching live speakers and getting to interact with experts is likely the next-best-thing to in-class training.

Announcing Microsoft Virtual Academy’s Introduction to MVC

image

Join Jon Galloway, Christopher Harrison in live video training, along with a handful of experts in the chat room, including yours truly, for a full day event on Microsoft Virtual Academy.

This is free, people. Like breathing.  You’re getting top-quality training, the ability to ask any questions you like and a really thorough examination of the basics of the MVC Framework.

You can REGISTER NOW and sit in on over 6 hours of free training.

Next Steps

What’s next in store? Keep following along with this blog series to get tuned up, then jump into the video on June 23rd to see it all in action.  Tomorrow, we’ll jump back into our series in full force, but please be sure to join the MVA on MVC!

Happy Coding!