如何从TagHelper中解析出根链接

5
在ASP.NET 5 MVC6 RC1中,我有一个ViewComponent,它被设计为代表我传统的“屏幕左侧”主菜单。我正在编写我的第一个TagHelper来表示每个菜单项链接。我卡在试图创建超链接的部分。如何解决“~/dashboard/summary”?如果我在此页面上显示菜单,则链接将显示为“/dashboard/~/dashboard/summary”。"@Url.Content(“...”)"显示"@Url.Content(“...”)",即不会被处理为razor。标签助手输出纯文本。理想情况下,我希望解决方案与.NET Core兼容,因为我最终的目标是实现.NET Core可部署解决方案。请参见下面:
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>            
    }
}

谢谢! 丹。

2个回答

13

ASP Core 2.0默认情况下似乎不包括IActionContextAccessorIServiceCollection中,因此您需要在启动时注册它才能使接受的解决方案起作用:

services.AddSingleton<IActionContextAccessor, ActionContextAccessor>();
否则,提供了一个属性可以将TagHelper的一个属性设置为扩展了ActionContextViewContext
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);
    }
}

注意: ViewContext 属性必须有一个公共的设置方法。


3
为什么ASP.Net Core 2使这更难实现?我认为访问UrlHelper应该更容易。 - S.Serpooshan

6
在您的标签助手中添加一个构造函数依赖项IUrlHelper。然后使用与视图中相同的扩展方法生成URL,例如IUrlHelper.Action(actionName, controllerName):
private IUrlHelper urlHelper;
...
public MainMenuLinkTagHelper (IUrlHelper urlHelper)
{
    this.urlHelper = urlHelper;
}
...
public override void Process(TagHelperContext context, TagHelperOutput output)
{
    output.TagName = "a";
    output.Attributes.Add("href", this.urlHelper.Action(this.Action, this.Controller));
    output.Content.SetHtmlContent("Click me");
} 

编辑:ASP Core版本1.0

现在不再可以直接注入IUrlHelper了。 您需要注入IActionContextAccessorIUrlHelperFactory,然后使用它们获取IUrlHelper。 例如:

private IUrlHelper UrlHelper => 
    this.urlHelperFactory.GetUrlHelper(this.actionAccessor.ActionContext);

非常棒 - 使用字符串url = _urlHelper.Action(Action, Controller, new { area=Area }); - DanAbdn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接