I wonder if someone can help with demonstrating how to create a IHtmlContent or HtmlString in ASP.NET Core, similar to what I previously have done in MVC5. I would normally declare a new MvcHtmlString method within a Helper class like so:
HtmlExtender.cs
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace WebApplication1.Helpers
{
public static class HtmlExtender
{
public static MvcHtmlString MenuLink(this HtmlHelper htmlHelper, string linkText, string controller, string action, string area, string anchorTitle)
{
var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
var url = urlHelper.Action(action, controller, new { area });
var anchor = new TagBuilder("a") {InnerHtml = HttpUtility.HtmlEncode(linkText)};
anchor.MergeAttribute("href", url);
anchor.Attributes.Add("title", anchorTitle);
var listItem = new TagBuilder("li") {InnerHtml = anchor.ToString(TagRenderMode.Normal)};
if (CheckForActiveItem(htmlHelper, controller, action, area))
{
listItem.GenerateId("menu_active");
}
return MvcHtmlString.Create(listItem.ToString(TagRenderMode.Normal));
}
private static bool CheckForActiveItem(HtmlHelper htmlHelper, string controller, string action, string area)
{
if (!CheckIfTokenMatches(htmlHelper, area, "area"))
return false;
if (!CheckIfValueMatches(htmlHelper, controller, "controller"))
return false;
return CheckIfValueMatches(htmlHelper, action, "action");
}
}
}
To use in a View would be @Html.MenuLink("Home", "Home", "Index", "", "Home")
also the inclusion of @using WebApplication1.Helpers
at the top of the View.
I'm unsure as to the use of HtmlString or IHtmlContent to achieve what I need, but my method requires access to the HttpContextAccessor, but I am a little unsure how to do this.
I have declared the HttpContextAccessor in the Startup.cs as I believe in ASP.NET Core 2.0 it is not declared by default as shown below but require assistance as how to use within the helper method.
Startup.cs
public void ConfigureServices(IServiceCollection serviceCollection)
{
serviceCollection.AddMvc();
serviceCollection.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
The new primitives in MVC Core are nice and easy to use. The TagBuilder implements IHtmlContent which can and should be used everywhere you are currently using MvcHtmlString. For your example above, simply remove the MvcHtmlString.Create and return the TagBuilder directly (adjusting to return IHtmlContent).
Other useful classes is HtmlContentBuilder, another type returning IHtmlContent, that can AppendHtml, similar to StringBuilder but for HTML content specifically. You can append many tag builders, which is very handy.
This is theoretically what you are after (I am found this GetUrlHelper extension elsewhere, I forget where).
public static IUrlHelper GetUrlHelper(this IHtmlHelper html)
{
var urlFactory = html.ViewContext.HttpContext.RequestServices.GetRequiredService<IUrlHelperFactory>();
var actionAccessor = html.ViewContext.HttpContext.RequestServices.GetRequiredService<IActionContextAccessor>();
return urlFactory.GetUrlHelper(actionAccessor.ActionContext);
}
public static IHtmlContent MenuLink(this IHtmlHelper htmlHelper, string linkText, string controller, string action, string area, string anchorTitle)
{
var urlHelper = htmlHelper.GetUrlHelper();
var url = urlHelper.Action(action, controller, new { area });
var anchor = new TagBuilder("a");
anchor.InnerHtml.Append(linkText);
anchor.MergeAttribute("href", url);
anchor.Attributes.Add("title", anchorTitle);
var listItem = new TagBuilder("li");
listItem.InnerHtml.AppendHtml(anchor);
if (CheckForActiveItem(htmlHelper, controller, action, area))
{
listItem.GenerateId("menu_active", "_");
}
return listItem;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With