In ASP.NET MVC, it may happen that you need to display a message to the user after a server is processing.
Out if a controller action redirects web, the message will be lost.
In most of my ASP.NET MVC projects I disable the session mechanism. Under these conditions, how to display a message to the user even if a redirect should take place?
So here is a simple solution to record a message to be consumed by the application as the user will display a page (View).
1. BaseController
It comes as a first step to create a BaseController that will inherit our controllers.
This controller will contain the notification to display to the user and a method to populate this property.
At the end of the action, if a notification exists, we store the notification in the ViewData to display it in a dedicated view:
- public abstract partial class BaseController: Controller {
- private string notification;
- /// <summary>
- /// Add notification to users
- /// </summary>
- /// <param name="message"></param>
- protected void AddNotification(string message) {
- notification = message;
- }
- /// <summary>
- /// </summary>
- /// <param name="filterContext"></param>
- protected override void OnResultExecuting(ResultExecutingContext filterContext) {
- if (!string.IsNullOrWhiteSpace(this.notification)) filterContext.Controller.ViewData.Add("PageLoadNotification", this.notification);
- }
- }
Since your controllers, you can now add notifications:
- public class HomeController: BaseController {
- public ActionResult Index() {
- AddNotification("hello");
- return View();
- }
- }
We will now create a _notifications.cshtml view in the folder "Views\Shared", that will display notifications.
(Razor syntax)
- @{
- var show = false;
- var notification = string.Empty;
- if(ViewData.ContainsKey("PageLoadNotification"))
- {
- notication = ViewData["PageLoadNotification"] as string;
- }
- show = !string.IsNullOrWhiteSpace(notification);
- }
- <div @(Html.Raw(show ? "" : "style=\"display:none;\""))>
- @if (show)
- {
- <text>
- @(notification)
- </text>
- }
- </div>
In our View "master" we will add the view partial _notifications.cshtml:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- </head>
- <body>
- <div class="page">
- @Html.Partial("_notifications")
- @RenderBody()
- <div class="clear"></div>
- </div>
- </body>
</html>
3. Redirects
The problem now is to manage a redirect. Imagine that an error occurs, or it redirects the user to another page wanting him to display the notification to the loading of the next page.
To do this, we will transit the message in a cookie that will be reset after having been consumed.
Here is a helper to manage your cookies easily:
- public static class CookieManager {#region Get / Set
- /// <summary>
- /// Set a value in cookie in the response
- /// </summary>
- /// <param name="cookieName">Nom du cookie</param>
- /// <param name="value">Valeur</param>
- public static void SetValue(string cookieName, string value) {
- if (System.Web.HttpContext.Current != null) {
- HttpCookie c = new HttpCookie(cookieName, value);
- c.Expires = DateTime.Now.AddMonths(6);
- if (System.Web.HttpContext.Current.Response.Cookies.Get(cookieName) == null) System.Web.HttpContext.Current.Response.Cookies.Add(c);
- else System.Web.HttpContext.Current.Response.Cookies.Set(c);
- }
- }
- /// <summary>
- /// get a value from Request cookie
- /// </summary>
- /// <param name="cookieName">Nom du cookie</param>
- /// <returns>Valeur dans le cookie, chaine vide sinon</returns>
- public static string GetValue(string cookieName) {
- if (System.Web.HttpContext.Current != null && System.Web.HttpContext.Current.Request.Cookies[cookieName] != null) return System.Web.HttpContext.Current.Request.Cookies[cookieName].Value;
- else return string.Empty;
- }#endregion
- }
Now, let's change our BaseController to store our notification in a cookie if redirected, or keep the current operation if a View is showing:
- public abstract partial class BaseController: Controller {
- private string notification;
- protected override void OnResultExecuting(ResultExecutingContext filterContext) {
- if (filterContext.Result is ViewResult) {
- var notificationCookie = CookieManager.GetValue("wscNotification");
- if (!string.IsNullOrWhiteSpace(notificationCookie)) {
- // There is an older notication :
- this.notification = HttpUtility.UrlDecode(notificationCookie);
- CookieManager.SetValue("wscNotification", string.Empty);
- }
- filterContext.Controller.ViewData.Add("PageLoadNotification", this.notification);
- } else {
- if (!string.IsNullOrWhiteSpace(this.notification)) {
- // We store notication in cooki for the next request :
- CookieManager.SetValue("wscNotification", HttpUtility.UrlEncode(this.notification));
- }
- }
- }
- }
Be careful
It is necessary to encode the data that you will store in your cookie for obvious security issues. Think to call methods HttpUtility.UrlEncode () and HttpUtility.UrlDecode () before storing the data in your cookie and vice versa. Could perfectly integrate these transformations into the CookieManager.
4. End
With this mechanism, you can now pass a message to your users from one page to another without going through the mechanism of the session!
Note that this always requires that your users accept cookies and you do not pass sensitive information, data that can be modified within the browser.
Bhavik PatelPosted Sep 22, 2016, 2:10 AM
Helpful
Vipul MalhotraPosted Jun 30, 2015, 7:59 AM
Thanks for sharing the article
Rahul Kumar SaxenaPosted Jun 30, 2015, 3:49 AM
good show
Pankaj Kumar ChoudharyPosted Jun 29, 2015, 8:36 PM
Nice Explain Sir.............
Chiheb ChebbiPosted Jun 29, 2015, 6:15 PM
nice
Mathieu MackPosted Jun 29, 2015, 4:11 PM
the line if (filterContext.Result is ViewResult) let workflow to know if the result of action is ViewResult, so the notication is added in ViewData, else if it's other Result, as RedirectResult or JsonResult ... we store notification in cookie.
Mathieu MackPosted Jun 29, 2015, 4:09 PM
Imagine that you make a POST. in the Action, you need to show a message that operation complete successfully or show error message, but the result of the action is a redirect (RedirectResult instead of Viewresult). For example, in wizard steps, you redirect user in other url after each POST. You don't have Session and do not want to add parameter in query string. This worklow let you to show message even if user is redirect to another url in your website ;)
Former memberPosted Jun 29, 2015, 12:51 PM
what this line does in your code if (filterContext.Result is ViewResult) ? when result will not be view result rather will be something different?
Former memberPosted Jun 29, 2015, 12:50 PM
Sorry i do not properly understand in what kind of situation people follow this approach. suppose i have 3 pages. in 1st page when user click button then a action gets called and we call this function AddNotification("hello"); which store hello as data in cookie and in 2nd page this message will be shown but what happen when redirect again redirect happen and user is redirected to 3rd page.....in 3rd page the same msg will be shown? when the hello will removed from cookie because cookie expiry set as 6 month. so for next six month same notification will be shown. please discuss in detail. thanks.
Santhakumar MunuswamyPosted Jun 29, 2015, 11:19 AM
Good one
Debasis SahaPosted Jun 29, 2015, 10:10 AM
Good