Day 25: Personalizing 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.

Back on Day 19 we introduced persistent storage for notifications, allowing us to pop a custom badge up in the navbar. This was great, but as we left it, it was creating notifications only in the seed method of our DbContext migrations configuration, and the notifications were shown to all users. Not too helpful for dialing in on specific details or messages for specific users.

Today we’re going to get that “everyone’s data” out of the mix, update our notifications so that they belong to a single user and then create a temporary way for us to add new, user-specific notifications to the site.

Clearing our DB and Seed Method

Let’s get those records (from our seed method) out of the database. Locate your DB in SQL Server Management Studio and delete the rows. Something this simple is adequate:

delete from notifications

Now, the only thing is that effort is all in vain if we don’t clean out our seed method. Each time the database configuration class is used to perform or check for migrations it will re-insert those rows.

Locate the Configuration class, which should be in \Migrations directory in the root of your solution. Comment out or delete all the code we added to upsert the notifications.

Extend our Notifications Class

Let’s next add a couple of properties to our Notification class, located in \Models.

public string UserId { get; set; }
public bool IsDismissed { get; set; }

Remember that when we modify a class that takes part in our Entity Framework works that we’ll also need to generate a migration and update the database to match our model. Type these commands into the Package Manager Console, updating the namespace appropriately:

Add-Migration PersonalNotifications -ConfigurationTypeName SimpleSite.Migrations.Configuration
Update-Database -ConfigurationTypeName SimpleSite.Migrations.Identity.Configuration

The first command creates a migration for us, and the second updates the database accordingly.

Updating our ActionFilter

So, if notifications belong only to users, we never want our filter to execute if the current request is for an unauthenticated user. We’ll also want to make sure that we only capture notifications for the user that is logged in, and then, only the notifications that have not yet been seen. 

Here’s the updated code for the NotificationFilter (located in \Filters):

public override void OnActionExecuted(ActionExecutedContext filterContext)
    if (!filterContext.HttpContext.User.Identity.IsAuthenticated) return;

    var userId = filterContext.HttpContext.User.Identity.GetUserId();

    var context = new SiteDataContext();
    var notifications = context.Notifications
        .Where(n => n.UserId == userId)
        .Where(n => !n.IsDismissed)
        .GroupBy(n => n.NotificationType)
        .Select(g => new NotificationViewModel
            Count = g.Count(),
            NotificationType = g.Key.ToString(),
            BadgeClass = NotificationType.Email == g.Key
                ? "success"
                : "info"

    filterContext.Controller.ViewBag.Notifications = notifications;

Scaffolding a Temporary Controller and View

The MVC Framework has some great scaffolding capabilities, as we’ve explored in minor detail so far. Today we’re going to use this feature to create our whole controller and the related views for all our CRUD operations. Right-click as you normally do on the controllers folder, and click Add->Controller.

This time ‘round, use the Scaffold for the “MVC5 Controller with views, using Entity Framework”. Fill out the options as follows:


You are selecting the Notification model, checking off “Generate views” and “Use a layout page”. The controller name should automatically be set to NotificationsController for you. Click Add to finish it out.


One more thing: you’re going to want an easy way to get your UserId – it’s what we’re using to match the notifications – so add the following to your Create view in Views\Notifications\Create.cshtml:

@if (User.Identity.IsAuthenticated)
    <p>Your User ID is <b>@User.Identity.GetUserId()</b></p>

That will output your UserId (which is a Guid) so that you can create notifications for yourself.

Now when you run the site, sign in and navigate to the /Notifications path. This will show you an empty list, but you’ll have a link to create some new records. Add some to the site, using your UserId, and watch the navbar light up.


Next Steps

Now, I did say this is a temporary solution. By no means would you actually have a situation where you’d have users enter their own notifications, you’d more likely have events happen in the system that require some notification to be required – perhaps the completion of a job or a required update to some business process.  That’s why we just used the scaffolding today…the NotificationsController and view are something that you’ll likely eventually just delete…and that’s okay! One of the nice things about scaffolding is that you’re not married to it. So delete it when you’re done with it.

In the real world, however, you would likely want users to be able to see and manage notifications in some way. Tomorrow we’ll look at getting the first of those bits in place.

  • somnath

    Add-Migration PersonalNotifications -ConfigurationTypeName SimpleSite.Migrations.Configuration
    Update-Database -ConfigurationTypeName SimpleSite.Migrations.Identity.Configuration

    here second line should be
    ConfigurationTypeName SimpleSite.Migrations.Configuration

  • Thomas

    Took me a couple of minutes to get the database updated to the new migration, so to help out others you need to change
    Update-Database -ConfigurationTypeName SimpleSite.Migrations.Identity.Configuration
    Update-Database -ConfigurationTypeName SimpleSite.Migrations.Configuration
    when we’re not creating the migration in the Identity folder as we were with the CssTheme earlier.

    • james.chambers

      Thanks Thomas! You’re correct, you’ll need to make sure the namespace/type matches exactly. Easiest is often to navigate to your class file and copy the namespace from there.


      • MostlyLucid

        Thanks for this — I was stuck for a bit.
        jc – perhaps take a minute and fix your post?

    • Alius Umbra

      Good catch. This tripped me up as well. I hope JC can take a minute to fix his otherwise flawless tutorial.

  • John Marsing

    Add using Microsoft.AspNet.Identity; to \Filters\NotificationFilter.cs

    • Ivan

      That helped, thanks! :)

  • Pingback: Friday Five - July 18, 2014 - The Microsoft MVP Award Program Blog - Site Home - MSDN Blogs()

  • Pingback: Friday Five – July 18, 2014 | CmdExec Technology News()

  • Pingback: Vadym Bobyr's Blog | Bootstrapping Mvc for the Next 30 Days()

  • paco

    hi james i have a question, what i need to do, to pass automatic the value of the user id, instead of copy paste

  • Alius Umbra

    I followed all the steps in this page, and I still got this error:
    An exception of type ‘System.InvalidOperationException’ occurred in EntityFramework.dll but was not handled in user code
    Additional information: The model backing the ‘SiteDataContext’ context has changed since the database was created. Consider using Code First Migrations to update the database (


    Looking at the database, it looks like the migration didn’t succeed, for some reason.