C# 如何在.NETCore2.2中正确创建锚辅助程序

C# 如何在.NETCore2.2中正确创建锚辅助程序,c#,asp.net-core,.net-core,C#,Asp.net Core,.net Core,我想创建一个HtmlHelper来显示带有materialize框架图标的链接 我写这段代码是因为我找不到类似的例子。我的代码可以工作,但至少看起来很糟糕。我想我应该使用UrlHelper和UrlAction,但我不知道怎么做 public static IHtmlContent IconActionLink(this IHtmlHelper helper, string iconName, object iconHtmlAttributes, string linkTe

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

我写这段代码是因为我找不到类似的例子。我的代码可以工作,但至少看起来很糟糕。我想我应该使用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;
}
我想知道如何正确地将RouteValue、Action和Controller插入标记。

在视图中,可以使用Url.Action从路由值、Action和Controller构建Url,并在href属性中使用它。要在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助手作为标记

这里有一个简单的标记帮助器,它可以为您提供一个图标标记

[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-*标记帮助器属性一起使用,并将任何其他属性(如数据id)添加到图标标记中

换句话说,标记帮助器唯一关心的是如何将原始iconName参数转换为表示图标的标记。其他一切——锚定标记构造、附加属性等——都可以留给更适合这些任务的其他事情处理。这是一个美丽的分离关注点


要使其正常工作,您可能需要重构MaterialIcon方法,甚至需要将该代码引入标记帮助器,具体取决于它的功能。

archer您是指anchor吗?我不知道什么是弓箭手助手,我是说锚。抱歉。我试图执行此操作,但出现以下错误:“UrlHelper不包含接受2个参数的构造函数”“ViewContext”“不包含”“RequestContext”“的定义,并且找不到接受”“ViewContext”“类型的第一个参数的可访问扩展方法”“RequestContext”“是否缺少using指令或程序集参考资料?”IHtmlHelper不包含“RouteCollection”的定义,并且找不到可访问的扩展方法“RouteCollection”,该扩展方法接受类型为“IHtmlHelper”的第一个参数。是否缺少using指令或程序集引用您可能导入了MVC和WebAPI名称空间的混合,或者只是导入了错误的名称空间。它们的类型名相互冲突,并且具有不同的构造函数参数。例如,vs..啊,我错过了asp.net-core标签。ASP.NET核心中的HTML帮助程序更适合向后兼容。考虑使用标签助手。它们是可组合的,允许您编写更自然的标记。如果可以的话,我将尝试为ASP.NET Core更新我的答案。
<a asp-action="someAction" asp-controller="theController" asp-route-id="@Model.Id"><icon name="fa-thumbs-up" data-id="@Model.Id" /></a>
<a href="/theController/someAction/1"><span class="fa fa-thumbs-up" data-id="1"></span></a>