Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to resolve ~ root link from a TagHelper

In ASP.NET 5 MVC6 RC1 - I have a ViewComponent which is designed to represent my traditional "left hand side of the screen" main menu.

I am writing my first TagHelper to represent each menu item link.

I am stuck at the part where I am trying to create a hyperlink.

How do I resolve ~/dashboard/summary?

If I display the menu on this page, the link appears as /dashboard/~/dashboard/summary.

@Url.Content("...") displays @Url.Content("...") i.e. is not processed as razor. The tag helper outputs pure.

Ideally, I would like the solution to be .NET Core compatible as I am eventually aiming for a .net core deployable solution.

See below:

namespace Website
{

    /// <summary>
    /// <MainMenuLink area="" controller="" action=""></MainMenuLink>
    /// 
    /// to render
    /// 
    ///  <a href="~/account/manage/ChangePassword" class="list-group-item @GetClassName("manage", "changepassword")">
    ///    <p class="list-group-item-text"><i class="fa fa-terminal"></i>&nbsp;&nbsp;Change my password</p>
    /// </a>
    /// 
    /// 
    /// </summary>
    [HtmlTargetElement(Attributes = "area, controller, action")]
    public class MainMenuLinkTagHelper : TagHelper
    {
        [HtmlAttributeName("area")]
        public string Area { get; set; }

        [HtmlAttributeName("controller")]
        public string Controller { get; set; }

        [HtmlAttributeName("action")]
        public string Action { get; set; }

        public UrlHelper urlHelper { get; set; }

        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            output.TagName = "a";    // Works    
            // Stuck here - I want ~/ to resolve to the base root.  
            // At the moment the address is here is localhost:XXXXX/dashboard/~/dashboard/summary

            // Would prefer to use a method which can be used with .net core and not System.Web

            output.Attributes.Add("href", "~/dashboard/summary");
            output.Content.SetHtmlContent("Click me");

        }        
        /// <summary>            
    }
}

Thanks! Dan.

like image 379
DanAbdn Avatar asked Dec 02 '22 15:12

DanAbdn


1 Answers

ASP Core 2.0 does not appear to include IActionContextAccessor in the IServiceCollection by default so you will need to register it at startup for the accepted solution to work:

services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();

Otherwise there is an attribute provided that can set a property of the TagHelper to the ViewContext which extends the ActionContext

using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.Routing;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;

[HtmlTargetElement("my-tag")]
public class MyTagHelper : TagHelper {

    private readonly IUrlHelperFactory urlHelperFactory;

    [ViewContext]
    [HtmlAttributeNotBound]
    public ViewContext ViewContext { get; set; }

    public MyTagHelper (IUrlHelperFactory urlHelperFactory) {
        this.urlHelperFactory = urlHelperFactory;
    }

    public override void Process(TagHelperContext context, TagHelperOutput output) {
        var urlHelper = urlHelperFactory.GetUrlHelper(ViewContext);
    }
}

note: The ViewContext property must have a public set method

like image 189
Peter Riesz Avatar answered Dec 09 '22 15:12

Peter Riesz