如何在.net Core 2.2中正确创建锚定助手

时间:2019-02-11 16:00:19

标签: c# asp.net-core .net-core

我想创建一个HtmlHelper来显示带有实现框架图标的链接。

我写这段代码是因为找不到类似的示例。我的代码有效,但至少看起来不好。我想我应该使用UrlHelper和UrlAction,但我不知道该怎么做。

public static IHtmlContent IconActionLink(this IHtmlHelper helper,
    string iconName,
    object iconHtmlAttributes,
    string linkText,
    string actionName,
    string controllerName,
    object routeValues,
    object linkHtmlAttributes)
{
    var content = new HtmlContentBuilder();
    var anchorStart = new TagBuilder("a");

    string routeValuesToString = "?";
    foreach(var r in new RouteValueDictionary(routeValues))
    {
        routeValuesToString += r.Key.ToString()+"="+r.Value.ToString()+"&";
    }
    routeValuesToString.Remove(routeValuesToString.Length-1);

    anchorStart.MergeAttribute("href", "../"+controllerName+"/"+actionName+"/"
        + routeValuesToString);

    anchorStart.MergeAttributes(new RouteValueDictionary(linkHtmlAttributes));
    anchorStart.InnerHtml.Append(linkText);
    anchorStart.TagRenderMode = TagRenderMode.StartTag;

    var icon = MaterialIcon(helper, iconName, iconHtmlAttributes);

    var anchorEnd = new TagBuilder("a") { TagRenderMode = TagRenderMode.EndTag };

    content.AppendHtml(anchorStart);
    content.AppendHtml(icon);
    content.AppendHtml(anchorEnd);

    return content;
}

我想知道如何正确地将RouteValues,Action,Controller插入标签。

1 个答案:

答案 0 :(得分:0)

在视图中,可以使用Url.Action()从路由值,操作和控制器构建URL,并在href属性中使用该URL。为此,需要在HTML帮助器中构造自己的URL帮助器。

// ASP.NET MVC
UrlHelper urlHelper = new UrlHelper(
    helper.ViewContext.RequestContext,
    helper.RouteCollection);

// ASP.NET Core
UrlHelper urlHelper = new UrlHelper(
    new ActionContext(
        helper.ViewContext.HttpContext,
        helper.ViewContext.RouteData,
        helper.ViewContext.ActionDescriptor));

现在,这部分代码:

string routeValuesToString = "?";
foreach(var r in new RouteValueDictionary(routeValues))
{
    routeValuesToString += r.Key.ToString()+"="+r.Value.ToString()+"&";
}
routeValuesToString.Remove(routeValuesToString.Length-1);

anchorStart.MergeAttribute("href", "../"+controllerName+"/"+actionName+"/"
    + routeValuesToString);

可以简化为:

anchorStart.MergeAttribute("href",
    urlHelper.Action(actionName, controllerName, routeValues));

这将正确地将值放在路径中,并将其放置在查询字符串中。


编辑-我提到了标签助手及其组合方式。您的HTML帮手所做的很多事情与图标本身无关,只是使其成为一个链接。 HTML帮助器可以接受渲染委托,但是您仍在使用自己的HTML帮助器作为a标签。

这里是icon标签的简单标签帮助程序,它将为您提供FontAwesome图标。

[HtmlTargetElement("icon", Attributes = "")]
public class IconTagHelper : TagHelper
{
    [HtmlAttributeName("name")]
    public string IconName { get; set; }

    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        output.TagName = "span";

        string classAttribute = $@"fa fa-{IconName}";

        output.Attributes.Add("class", classAttribute);
    }
}

现在,您可以将普通的a标签与asp- *标签助手属性一起使用,并将所有其他属性(例如data-id)添加到icon标签中。

<a asp-action="someAction" asp-controller="theController" asp-route-id="@Model.Id"><icon name="fa-thumbs-up" data-id="@Model.Id" /></a>

使用Model.Id == 1,它将呈现如下内容:

<a href="/theController/someAction/1"><span class="fa fa-thumbs-up" data-id="1"></span></a>

换句话说,标记助手仅关心的是如何将原始的iconName参数转换为表示图标的标记。其他所有内容(锚标记构造,其他属性等)可以留给其他更适合这些任务的内容。这是令人担忧的分离。

要使其正常工作,您可能需要重构MaterialIcon方法,甚至根据其功能将代码带入标签帮助器。