ASP.NET MVC Guidelines: Notifications

Posted in ASP.NET MVC,Ajax,MSP by bcardiff on the March 11th, 2009

While developing a web application a developer should build some infrastructure for the whole system. ASP.NET MVC is not the exception. The fact that ASP.NET MVC is a framework, it doesn’t mean that covers 100% of the necessity a developer will have during the development, but it should let you fill the gap. This gap could be filled by third party libraries or just by something ad-hoc you develop.

I saw (and develop) some kind of notifications solutions in order to tell the user that something (good or bad) have just happened due to his action eg.: “your password has been changed”, “you have new messages”, etc. These implementations were constrained to the MVC-way, letting the model has a notification property, letting the view show that property, etc. They could, but as soon as you reach some Post-Redirect-Get, or some partial page AJAX call, or JSON AJAX call you will get into troubles.

Along this post I will show a notification solution that play nice with all these scenarios with a unify way. I don’t I’m telling something new here, just sharing the experience and thuoghts. I will assume that the notifications are plain strings, but it could be extended to include a kind field (info, warning, error).

Download sample code for ASP.NET MVC RC 2. Try test buttons and changing your password.

Interface

The first thing is how we expect to leave a notification. Since the notification capability should be used a lot I prefer to make them available without needing to change the Model or ActionResult, so lets create a INotificationService. In order to play nice with designs and testing prefer to let the controllers get a reference to:

public interface INotificationService
{
    void Send(string message);
}

How to use it

All the controllers should have HandleNotificationAttribute applied, later we will see what is this for. The controller that want to send a notification will need to get a reference to an INotificationService. During the execution of the action, the method Send could be called as many times as you want. You are able to return what ever ActionResult you want. But if doing a redirect, be sure to use a RedirectToRouteResult (i.e. suggesting ASP.NET MVC way to send HTTP Redirects).

[HandleNotification]
public class SomeController : Controller
{
    INotificationService notification;

    public SomeController(INotificationService notification)
    {
        this.notification = notification;
    }

    public ViewResult Index()
    {
        notification.Send("Welcome!");
        // Create some model for the view
        return View();
    }

    public ActionResult RedirectCall()
    {
        // Perform changes
        notification.Send("data saved");
        return RedirectToAction("Index", "Home");
    }

    public JsonResult JsonAjaxCall()
    {
        notification.Send("Lorem ipsum");
        notification.Send("dolor sit amet");
        return Json(new { A = 1, B = "lorem" });
    }

}

As it can be seen, it is straight forward the usage. The INotificationService only expose a method to add notification, but not to clear them.

Client side

Just for encapsulation I choose to create a ViewUserControl that it should be included at the MasterPage, or at every respose page of a non-AJAX HTTP Request.

<%@ Master ... %>
<%@ Register TagPrefix="core" TagName="notifications"
    Src="~/Core/Notifications/ShowNotifications.ascx" %>
<!DOCTYPE html PUBLIC ...>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <!-- ... -->
    <core:notifications runat="server" />
</head>
<!-- ... -->
</html>

The client side use Javascript to display notification, in the sample below I use jGrowl (and jQuery). It is easy to change it to generate some just plain divs inside an identified element if you prefer.

Somewhere in the code of ShowNotifications.ascx the following code defines how a notification is shown:

function showNotification(msg) {
    $.jGrowl(msg);
}

The HandleNotificationAttribute has the responsibility to expose the recent notifications in the way the ShowNotifications.ascx is expecting them.

The following section goes trough implementation details, which is not the most interesting part in the article.

How it works

I will detail how each scenarios is supported:

non-AJAX/non-redirect Actions

The action have just store some notifications. The HandleNotificationAttribute add to the ViewData a HandleNotificationInfo that the ShowNotifications.ascx will use to render some calls to the showNotification functions.

AJAX Actions (JSON or Partial View)

The JSON calls force us to send the notification out-of-the-band, I choose to use cookies. So, if the HandleNotificationInfo detects that the request is an AJAX request, it serialize the HandleNotificationInfo using JSON. The ShowNotifications.ascx attach to AJAX Complete event (using jQuery) and pulls recently added cookie, and remove it.

Up to this point the storage of the notifications (INotificationRepository) could be implemented inside the request life cycle, but in order to support the next scenario we will use an implementation of INotificationRepository that use the HTTP Session object.

Post-Redirect-Get

When the action tells the INotificationService to send a notification, it is stored (as in every call) using the INotificationRepository. In this case, the HandleNotification performs no action, remember it was a POST request. The client receives a Redirect which performs a GET that will fall in the previous cases. Since the INotificationRepository use HTTP Session object, upon the action executed by the GET is completed, the HandleNotification will perform the usual task: pop the stored notifications in INotificationRepository and expose them to the client.

A final remark is that since Attributes can’t be injected with dependencies I expose a static property that is set upon Application_Start, in Global.asax.

Hope you find it useful. I’m more interesting in the overall solution than in the actual implementation: that is, enhancing the ASP.NET MVC framework with some services you would need for a better application development.

2 Responses to 'ASP.NET MVC Guidelines: Notifications'

Subscribe to comments with RSS or TrackBack to 'ASP.NET MVC Guidelines: Notifications'.


  1. on February 22nd, 2010 at 1:59 pm

    Good article! Thanks for sharing.

  2. Adeel Zahid said,

    on July 22nd, 2010 at 6:45 am

    hay Brain,

    it is nice article. however, i don’t see how one can implement push approach using this architecture. for example i send mail to a list of 20 people, i need something to find out receivers and give them notifications if they are online. the functionality, however, is done in much sophisticated way. if i did the same thing i would use bunch of ViewData in controller actions. i m sure u must have plan how to extend this to push notifications

    regards
    Adeel

Leave a Reply