Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flash equivalent in ASP.NET MVC 3

Tags:

asp.net-mvc

There is a feature called 'flash' in ruby on rails where you can put a message in 'flash', redirect, and the message is available in the next action.

Example of the use of flash:

There is a controller action Account.ChangePassword. If password change is successful, ChangePassword will fill flash with a message 'Password change successful', and then redirects to Account.Profile. In Account.Profile, the message is available so it can be displayed in the profile page.

Is there something equivalent in ASP.NET MVC 3?

I know I can build this feature myself using tempdata, but does MVC 3 have something built in?

like image 779
Endy Tjahjono Avatar asked Apr 07 '11 12:04

Endy Tjahjono


3 Answers

Endy,

I 'borrowed' this from the tekpub series:

namespace System.Web.Mvc {
    public static class FlashHelpers {

        public static void FlashInfo(this Controller controller,string message) {
            controller.TempData["info"] = message;
        }
        public static void FlashWarning(this Controller controller, string message) {
            controller.TempData["warning"] = message;
        }
        public static void FlashError(this Controller controller, string message) {
            controller.TempData["error"] = message;
        }

        public static string Flash(this HtmlHelper helper) {

            var message = "";
            var className = "";
            if (helper.ViewContext.TempData["info"] != null) {
                message =helper.ViewContext.TempData["info"].ToString();
                className = "info";
            } else if (helper.ViewContext.TempData["warning"] != null) {
                message = helper.ViewContext.TempData["warning"].ToString();
                className = "warning";
            } else if (helper.ViewContext.TempData["error"] != null) {
                message = helper.ViewContext.TempData["error"].ToString();
                className = "error";
            }
            var sb = new StringBuilder();
            if (!String.IsNullOrEmpty(message)) {
                sb.AppendLine("<script>");
                sb.AppendLine("$(document).ready(function() {");
                //sb.AppendFormat("$('#flash').html('{0}');", message);
                sb.AppendFormat("$('#flash').html('{0}');", HttpUtility.HtmlEncode(message));
                sb.AppendFormat("$('#flash').toggleClass('{0}');", className);
                sb.AppendLine("$('#flash').slideDown('slow');");
                sb.AppendLine("$('#flash').click(function(){$('#flash').toggle('highlight')});");
                sb.AppendLine("});");
                sb.AppendLine("</script>");
            }
            return sb.ToString();
        }

    }
}

typical usage (inside controller):

public ActionResult Delete(int id, FormCollection collection)
{
    var item = _session.Single<UserActions>(x=>x.ID == id);
    try
    {
        _session.Delete<UserActions>(item);
        _session.CommitChanges();
        this.FlashInfo("UserAction deleted ...");
        return RedirectToAction("Index");
    }
    catch
    {
        this.FlashError("There was an error deleting this record");
        return View("Edit",item);
    }
}

the css is pretty straightfwd too:

.info
{
    background-color: #CCFFCC;
    border-top: 1px solid #FFCC66;
    border-bottom: 4px solid #FFCC66;
    padding: 6px;
    font-family: helvetica;
    font-size: 1.1em;
    text-align: center;
    border-top-color: #006600;
    border-bottom-color: #006600;
    font-weight: bold;
    color: #339933;
    cursor:pointer;
}
.warning
{
    background-color: #FFFF99;
    border-top: 1px solid #FFCC66;
    border-bottom: 4px solid #FFCC66;
    padding: 6px;
    font-family: helvetica;
    font-size: 0.9em;
    text-align: center;
    border-top-color: #CC9900;
    border-bottom-color: #CC9900;
    font-weight: bold;
    color: #663300;
    cursor:pointer;
}
.error
{
    background-color: #FFCC99;
    border-top: 1px solid #FFCC66;
    border-bottom: 4px solid #FFCC66;
    padding: 4px;
    font-family: helvetica;
    font-size: 1.1em;
    text-align: center;
    border-top-color: #800000;
    border-bottom-color: #800000;
    font-weight: bold;
    color: #990000;
    cursor:pointer;
}

and in your site.master

<%=Html.Flash() %>
<body>
    <div id="flash" style="display: none">
    </div>
.... etc
</body>

enjoy...

like image 120
jim tollan Avatar answered Nov 06 '22 09:11

jim tollan


No, the TempData solution is what you are looking for.

like image 21
Swaff Avatar answered Nov 06 '22 09:11

Swaff


I want to upgrade Jim's answer to use MVC 3's new helper functions.

Helper functions make it easy to write functions that primarily return Html/javascript so you don't have to use string builder or string concatenation. It results in much cleaner code.

FlashHelpers.cs :

namespace System.Web.Mvc {

    public static class FlashHelpers {

        public static void FlashInfo(this Controller controller,string message) {
            controller.TempData["info"] = message;
        }
        public static void FlashWarning(this Controller controller, string message) {
            controller.TempData["warning"] = message;
        }
        public static void FlashError(this Controller controller, string message) {
            controller.TempData["error"] = message;
        }
    }
}

Then you create the ASP.NET App_Code folder and create a .cshtml file there (Flash.cshtml probably) and paste in the following code

App_Code/Flash.cshtml :

@helper FlashMessage(TempDataDictionary tempData){
    var message = "";
    var className = "";
    if (tempData["info"] != null)
    {
        message = tempData["info"].ToString();
        className = "flashInfo";
    }
    else if (tempData["warning"] != null)
    {
        message = tempData["warning"].ToString();
        className = "flashWarning";
    }
    else if (tempData["error"] != null)
    {
        message = tempData["error"].ToString();
        className = "flashError";
    }
    if (!String.IsNullOrEmpty(message))
    {
        <script type="text/javascript">
            $(document).ready(function() {
            $('#flash').html('@message');
            $('#flash').toggleClass('@className');
            $('#flash').slideDown('slow');
            $('#flash').click(function(){$('#flash').toggle('highlight')});
            });
        </script>
    }
}

This is doing what the Flash function was doing before but in a much cleaner way.

Rest of the things stay the same as in Jim's answer except the way you call it. Instead of using @Html.Flash(), you need to call it like so:

@Flash.FlashMessage(TempData)

Please note that Flash in the above line is the name of the .cshtml file in the App_Code folder.

Hope it helps.

like image 16
Imran Rashid Avatar answered Nov 06 '22 10:11

Imran Rashid