asp.net MVC6 Implementing a tagbuilder class and get error on ".ToString"

2.4k Views Asked by At

I am getting compile errors when attempting to implement the message class from Levelnis's Blog.

The class in question is:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.Rendering;

namespace Notifier.Helpers.MessageNotifier
{
    public class Message
    {
        public MessageSeverity Severity { get; set; }

        public string Text { get; set; }

        public string Generate()
        {
            var isDismissable = Severity != MessageSeverity.Danger;
            if (Severity == MessageSeverity.None) Severity = MessageSeverity.Info;
            var sb = new StringBuilder();
            var divTag = new TagBuilder("div");
            divTag.AddCssClass("alert fade in");
            divTag.AddCssClass("alert-" + Severity.ToString().ToLower());


            var spanTag = new TagBuilder("span");
            spanTag.MergeAttribute("id", "MessageContent");

            if (isDismissable)
            {
                divTag.AddCssClass("alert-dismissable");
            }

            sb.Append(divTag.ToString(TagRenderMode.StartTag));

            if (isDismissable)
            {
                var buttonTag = new TagBuilder("button");
                buttonTag.MergeAttribute("class", "close");
                buttonTag.MergeAttribute("data-dismiss", "alert");
                buttonTag.MergeAttribute("aria-hidden", "true");
                buttonTag.InnerHtml = "×";
                sb.Append(buttonTag.ToString(TagRenderMode.Normal));
            }

            sb.Append(spanTag.ToString(TagRenderMode.StartTag));
            sb.Append(Text);
            sb.Append(spanTag.ToString(TagRenderMode.EndTag));
            sb.Append(divTag.ToString(TagRenderMode.EndTag));

            return sb.ToString();
        }
    }
}

I am getting two errors - the first relates to ".ToString" on the line:

sb.Append(divTag.ToString(TagRenderMode.StartTag));

and it says:

No overload for method 'ToString' takes 1 arguments

The second error relates to the line:

buttonTag.InnerHtml = "×";

and it says:

Property or indexer 'TagBuilder.InnerHtml' cannot be assigned to -- it is read only

I have had a look at the documentation and other posts but so far I have not found anything that can help me modify this to compile correctly...

Are these methods implemented differently in Asp.net-core and if not can someone suggest another way of doing these lines?

2

There are 2 best solutions below

0
si2030 On

This was all to do with implementing a way of placing messages on the subsequent page - initially using Levilnis's Blog.

Not able to implement this without issues I stepped back and looked for another way of doing this. I used an approach presented by Mister James and in particular using a baseController to hold all my possible messages. I simplified it a bit as I didn't need to run multiple messages - just one per page.

public class BaseController : Controller
{
    public void Success(string message, bool dismissable = false)
    {
        AddAlert(AlertStyles.Success, message, dismissable);
    }

    public void Information(string message, bool dismissable = false)
    {
        AddAlert(AlertStyles.Information, message, dismissable);
    }

    public void Warning(string message, bool dismissable = false)
    {
        AddAlert(AlertStyles.Warning, message, dismissable);
    }

    public void Danger(string message, bool dismissable = false)
    {
        AddAlert(AlertStyles.Danger, message, dismissable);
    }

    private void AddAlert(string alertStyle, string message, bool dismissable)
    {
        var alert = new Alert
        {
            AlertStyle = alertStyle,
            Message = message,
            Dismissable = dismissable
        };

         TempData.Put(Alert.TempDataKey, alert);
    }

}

There was a wrinkle in that you cannot, in MVC6, send complex objects using Tempdata. This was solved using @Hem's answer in this Stackoverflow question where he suggests using an extension that converts the complex object into a json string. For this to work I did have t oadd the using "using Newtonsoft.Json;".

public static class TempDataExtensions
{
    public static void Put<T>(this ITempDataDictionary tempData, string key, T value) where T : class
    {
        tempData[key] = JsonConvert.SerializeObject(value);
    }

    public static T Get<T>(this ITempDataDictionary tempData, string key) where T : class
    {
        object o;
        tempData.TryGetValue(key, out o);
        return o == null ? null : JsonConvert.DeserializeObject<T>((string)o);
    }
}

This now works like a charm.

0
Kunal Chiddarwar On

It seems TagBuilder does not work the same in MVC6 as it was in MVC5.

Instead of the ToString() method use StringWriter and the WriteTo() method as below:

StringBuilder result = new StringBuilder();
TagBuilder tag = new TagBuilder("a");
tag.AddCssClass("btn btn-default");  
using (var writer = new StringWriter())
{
  tag.WriteTo(writer, HtmlEncoder.Default);
  result.Append(writer.ToString());
}  

To set the InnerHtml use the Append() method as below:

tag.InnerHtml.Append(i.ToString()); 

This way it worked for me.