Extending ASP.NET MVC Redirects with Confirmations

One of the most common tasks in any application is displaying confirmation messages after execution of a back-end operation. The standard way to accomplish this is to use TempData to persist messages from one action to another during a redirect. What I’d like to show is a very crafty way of extending the redirect behavior in MVC to include confirmation messages via TempData.

What we’re looking to do is write extension methods for RedirectToRouteResult and RedirectResult named WithConfirmation to append custom confirmation message to TempData dictionary. The end result should look like shown in the following snippet.

[HttpPost]
public ActionResult DoSomething()
{
    return this
        .RedirectToAction("Index", "Home")
        .WithConfirmation("Insert message here");
}

To accomplish this we’ll want to implement a custom ActionResult to act as the pass-through layer, which adds the confirmation message to TempData and executes the original redirect result.

public class RedirectWithConfirmationMessageResult : ActionResult
{
    private readonly string message;

    public RedirectWithConfirmationMessageResult(ActionResult redirectBaseResult, string message)
    {
        BaseResult = redirectBaseResult;
        this.message = message;
    }

    public ActionResult BaseResult { get; private set; }

    public override void ExecuteResult(ControllerContext context)
    {
        context.Controller.TempData["Message.Notification"] = this.message;

        BaseResult.ExecuteResult(context);
    }
}

Now, we’ll write the extension methods.

public static class RedirectExtensions
{
    public static RedirectWithConfirmationMessageResult WithConfirmation(this RedirectToRouteResult instance, string message)
    {
        return new RedirectWithConfirmationMessageResult(instance, message);
    }

    public static RedirectWithConfirmationMessageResult WithConfirmation(this RedirectResult instance, string message)
    {
        return new RedirectWithConfirmationMessageResult(instance, message);
    }        
}

While this example shows only confirmation messages, it can be easily extended to support any message types. I’ll leave that as an exercise for the reader.