Success message from Controller to View
Expanding from Brad Christie's answer, I created a NuGet package, BootstrapNotifications, that will do this for you with built-in Bootstrap3 support. This package also supports multiple notification types (error, warning, success, and info) with pre-styled alerts and is easily extendable.
The extension supports multiple notifications per request of the same type and different types elegantly.
The Code
NotificationExtensions.cs:
public static class NotificationExtensions
{
private static IDictionary<String, String> NotificationKey = new Dictionary<String, String>
{
{ "Error", "App.Notifications.Error" },
{ "Warning", "App.Notifications.Warning" },
{ "Success", "App.Notifications.Success" },
{ "Info", "App.Notifications.Info" }
};
public static void AddNotification(this ControllerBase controller, String message, String notificationType)
{
string NotificationKey = getNotificationKeyByType(notificationType);
ICollection<String> messages = controller.TempData[NotificationKey] as ICollection<String>;
if (messages == null)
{
controller.TempData[NotificationKey] = (messages = new HashSet<String>());
}
messages.Add(message);
}
public static IEnumerable<String> GetNotifications(this HtmlHelper htmlHelper, String notificationType)
{
string NotificationKey = getNotificationKeyByType(notificationType);
return htmlHelper.ViewContext.Controller.TempData[NotificationKey] as ICollection<String> ?? null;
}
private static string getNotificationKeyByType(string notificationType)
{
try
{
return NotificationKey[notificationType];
}
catch (IndexOutOfRangeException e)
{
ArgumentException exception = new ArgumentException("Key is invalid", "notificationType", e);
throw exception;
}
}
}
public static class NotificationType
{
public const string ERROR = "Error";
public const string WARNING = "Warning";
public const string SUCCESS = "Success";
public const string INFO = "Info";
}
_Notifications.cshtml:
@using YourApp.Extensions
@{
var errorList = Html.GetNotifications(NotificationType.ERROR);
var warningList = Html.GetNotifications(NotificationType.WARNING);
var successList = Html.GetNotifications(NotificationType.SUCCESS);
var infoList = Html.GetNotifications(NotificationType.INFO);
}
<!-- display errors -->
@if (errorList != null)
{
<div class="alert alert-danger alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
@if(errorList.Count() > 1){
<strong><span class="glyphicon glyphicon-remove"></span> There are @errorList.Count() errors: </strong>
<ul>
@foreach (String message in errorList)
{
<li>@Html.Raw(message)</li>
}
</ul>
}
else{
<strong><span class="glyphicon glyphicon-remove"></span> Error: </strong>
@Html.Raw(errorList.First())
}
</div>
}
<!-- display warnings -->
@if (warningList != null)
{
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
@if(warningList.Count() > 1){
<strong><span class="glyphicon glyphicon-warning-sign"></span> There are @warningList.Count() warnings: </strong>
<ul>
@foreach (String message in warningList)
{
<li>@Html.Raw(message)</li>
}
</ul>
}
else{
<strong><span class="glyphicon glyphicon-warning-sign"></span> Warning: </strong>
@Html.Raw(warningList.First())
}
</div>
}
<!-- display success -->
@if (successList != null)
{
<div class="alert alert-success alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
@if(successList.Count() > 1){
<strong><span class="glyphicon glyphicon-ok"></span> There are @successList.Count() successful notifications: </strong>
<ul>
@foreach (String message in successList)
{
<li>@Html.Raw(message)</li>
}
</ul>
}
else{
<strong><span class="glyphicon glyphicon-ok"></span> Success! </strong>
@Html.Raw(successList.First())
}
</div>
}
<!-- display success -->
@if (infoList != null)
{
<div class="alert alert-info alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
@if(infoList.Count() > 1){
<strong><span class="glyphicon glyphicon-info-sign"></span> There are @infoList.Count() notifications: </strong>
<ul>
@foreach (String message in infoList)
{
<li>@Html.Raw(message)</li>
}
</ul>
}
else{
<strong><span class="glyphicon glyphicon-info-sign"></span> </strong>
@Html.Raw(infoList.First())
}
</div>
}
To see all of this code and how its used, you can download a full working demo from github.
There are a few ways to skin this cat. You could use the ViewBag:
ViewBag.SuccessMessage = "<p>Success!</p>";
Then in your view you could render it to the page:
@ViewBag.SuccessMessage
I'm not a fan of the ViewBag, so I typically have a ViewModel object created that holds all the data I would need for my particular view. And a success message would be just that kind of data:
public MyViewModel{
public bool IsSuccess {get;set;}
}
Then in your controller, you would pass this ViewModel to your stongly-typed view
[HttpPost]
public ActionResult Update(MyViewModel vm){
//Glorious code!
return View(vm)
}
Finally, just check it in your view and print a message if it succeeds:
@if(vm.IsSuccess){
<p>Here is an amazing success message!</p>
}
Also, instead of that, you can use TempData, which works like the ViewBag but only lasts until the end of your next request and is then discarded:
TempData["SuccessMessage"] = "Success!";