Quick Tip: How to pass visual alerts with an HTMLHelper

Today, we discuss the ability to create notifications to our users when something goes wrong in a process/controller using an HtmlHelper called ViewMessageHelper.

Written by Jonathan "JD" Danylko • Last Updated: • MVC •
ViewMessage HtmlHelper

When I recently wrote about HtmlHelpers, I discussed how some of the helpers were used to display different types of data through the Media objects. As a reminder, HtmlHelpers are basically extension methods that can extend any class.

Recently, I had a user ask about how to display messages to users when something goes wrong. If you've read my Make a BaseViewModel for your Layouts, you know where I'm going with this.

This time around, I thought we could write something of benefit to most Bootstrap designers/developers: A ViewMessage HtmlHelper.

Let's set up the requirements for the ViewMessage HtmlHelper.

It will display a Bootstrap alert if there is a message passed through the ViewModel. This message can be a success, error, or informational message. The nice thing about the ViewMessage HtmlHelper is that if we don't pass it into our views, it won't display anything.

So let's get started!

Time to code!

First, let's define our ViewMessage model and attach it to our BaseViewModel.

Models\ViewMessage.cs

public enum MessageType
{
    [Description("Information")]
    Information,
    [Description("Warning")]
    Warning,
    [Description("Error")]
    Error,
    [Description("Success")]
    Success
}
public class ViewMessage
{
    public ViewMessage()
    {
        MsgType = MessageType.Information;
        MsgText = String.Empty;
        MsgTitle = String.Empty;
    }
    public ViewMessage(MessageType msgType, string msg, string title)
    {
        MsgType = msgType;
        MsgText = msg;
        MsgTitle = title;
    }
    public MessageType MsgType { getset; }
    public string MsgText { getset; }
    public string MsgTitle { getset; }
}

ViewModels\BaseViewModel.cs

public class BaseViewModel : IBaseViewModel
{
    public string Title { getset; }
    public string MetaDescription { getset; }
    public string MetaKeywords { getset; }
    public ViewMessage Message { getset; }
    
    public Login CurrentUser { getset; }
    public Uri Url { getset; }
}

Next, we need our HtmlHelper defined:

public static class ViewMessageHelper
{
    public static MvcHtmlString MessageAlert(this HtmlHelper helper, ViewMessage msg)
    {
    } }

Pretty standard extension method, right?

When creating HtmlHelpers, I always overload it with additional Html attributes in case I want to add a class or id. So let's add another extension method to take HTML attributes.

public static class ViewMessageHelper
{
    public static MvcHtmlString MessageAlert(this HtmlHelper helper, ViewMessage msg)
    {
        return MessageAlert(helper, msg, null);
    }
    public static MvcHtmlString MessageAlert(this HtmlHelper helper, ViewMessage msg,
        object htmlAttributes)
    {
        if (msg == null || String.IsNullOrEmpty(msg.MsgText))
        {
            return MvcHtmlString.Empty;
        }
    }
}

Notice that when we don't have a ViewMessage or no message at all, then we return a empty MvcHtmlString.

But now what we need is the actual creation of the message.

Here is the entire ViewMessageHelper to display an alert on your page.

Helpers\Html\ViewMessageHelper.cs

public static class ViewMessageHelpers
{
    public static MvcHtmlString MessageAlert(this HtmlHelper helper, ViewMessage msg)
    {
        return MessageAlert(helper, msg, null);
    }
    public static MvcHtmlString MessageAlert(this HtmlHelper helper, ViewMessage msg,
                                       object htmlAttributes)
    {
        if (msg == null || String.IsNullOrEmpty(msg.MsgText))
        {
            return MvcHtmlString.Empty;
        }
        return BuildMessageHelper(helper, msg, htmlAttributes);
    }
    private static MvcHtmlString BuildMessageHelper(this HtmlHelper helper, ViewMessage msg, 
                                             object attributes)
    {
        // Create the container
        var ulMsg = new TagBuilder("div");
        ulMsg.MergeAttribute("data-alert""alert alert-sm");
        switch(msg.MsgType)
        {
            case MessageType.Information:
                ulMsg.MergeAttribute("class""alert alert-info fade in");
                break;
            case MessageType.Error:
                ulMsg.MergeAttribute("class""alert alert-danger fade in");
                break;
            case MessageType.Warning:
                ulMsg.MergeAttribute("class""alert alert-warning fade in");
                break;
            case MessageType.Success:
                ulMsg.MergeAttribute("class""alert alert-success fade in");
                break;
        }
        
        ulMsg.MergeAttributes(new RouteValueDictionary(attributes));
        
        var sb = new StringBuilder();
        sb.Append("<a class=\"close\" data-dismiss=\"alert\" href=\"#\">×</a>");
        sb.AppendFormat("<p>{0}</p>", msg.MsgText);
        ulMsg.InnerHtml = sb.ToString();
        return MvcHtmlString.Create(ulMsg.ToString(TagRenderMode.Normal));
    }
}

So now when we want to display a message, we add the message to our view like this:

@Html.MessageAlert(Model.Message) 

Anytime we want a message, we create it in our ViewModelBuilder, pass it through our ViewModel, and use our HtmlHelper to display it.

Conclusion

The ViewMessage HtmlHelper is just one of the various helpers that I'll be discussing on this blog. Keep in touch and I will be writing some more HtmlHelpers for my audience. Stay tuned!

If you are looking for an Html Helper, send me an email or post a comment below and we'll write something up to help you out with your HtmlHelper.

Did you like this content? Show your support by buying me a coffee.

Buy me a coffee  Buy me a coffee
Picture of Jonathan "JD" Danylko

Jonathan Danylko is a web architect and entrepreneur who's been programming for over 25 years. He's developed websites for small, medium, and Fortune 500 companies since 1996.

He currently works at Insight Enterprises as an Principal Software Engineer Architect.

When asked what he likes to do in his spare time, he replies, "I like to write and I like to code. I also like to write about code."

comments powered by Disqus