实现使用路由系统的HtmlHelper扩展

问题描述 投票:0回答:1

我正在尝试为HtmlHelper实现我自己的扩展,它将以与ActionLink类似的方式输出链接。

我知道我可以用TagBuilder轻松地做到这一点,但是我想利用路由系统的能力构建出口网址,如Scott Guthrie在this vintage article中所描述的那样。

我的应用程序以组织为中心。一个用户可以创建一个组织,一个组织可以有多个位置。主要行动发生在当前位置。我认为组织是我的应用程序中的租户,组织ID通过URL发送。

这是上面的路由配置:

routes.MapRoute(
    name: "Tenant",
    url: "Tenants/{tenantId}/{action}",
    defaults: new
    {
        controller = "Organizations",
        action = "Dashboard",
        id = UrlParameter.Optional
    }
);

routes.MapRoute(
    name: "TenantLocation",
    url: "Tenants/{tenantId}/Locations/{locationId}/{controller}/{action}/{id}",
    defaults: new
    {
        controller = "Dashboard",
        action = "Index",
        id = UrlParameter.Optional
    }
);

对于路线“租户”,控制器始终是组织。该部分应用程序负责整个组织的管理操作。此处的上下文包含租户ID。

对于路径“TenantLocation”,上下文在位置内移动,因此上下文包含租户ID和位置ID。

现在,我想为HtmlHelper创建两个名为TenantActionLink和TenantLocationActionLink的扩展方法,以生成如下链接:

/Tenants/150/Dashboard

要么

/Tenants/150/Locations/300/Team/Edit/1000

部件“/ Tenants / 150 / Locations / 300 /”可以被视为前缀到URL的前缀,id由ActionFilterAttribute提取并作为属性存储在BaseController类中。

正如我所提到的,我可以使用TagBuilder轻松生成链接,但如果我稍后更改路由,则必须更新所有视图和控制器中租户操作链接方法的所有调用。

关于如何解决这个问题的任何建议?我正在使用ASP.NET MVC 5和.NET Framework 4.6.1

谢谢。


更新回答Stephen Muecke的questions

你都尝试了些什么?

我实现了这样的扩展(为简单起见,我只包含TenantLocationActionLink的代码,另一个类似):

public static MvcHtmlString TenantLocationActionLink(this HtmlHelper helper,
    int tenandId,
    int locationId,
    string linkText,
    string actionName,
    string controllerName,
    object htmlAttributes = null)
{
    var url = $"/Tenants/{tenandId}/Locations/{locationId}/{controllerName}/{actionName}";

    var tagBuilder = new TagBuilder("a");
    tagBuilder.InnerHtml = linkText;
    tagBuilder.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
    tagBuilder.MergeAttribute("href", url);

    return new MvcHtmlString(tagBuilder.ToString(TagRenderMode.Normal));
}

你有什么问题?

我无法弄清楚如何处理routeValues。我的实现在某种程度上是从更灵活的ActionLink实现的一个步骤,特别是因为它没有考虑routeValues。当路由配置变得更复杂时,我将如何处理这种情况?

你期望你的扩展方法对内置的ActionLink()或RouteLink()没有做什么?

如上所述,在租户和位置ID之前添加前缀。我怎样才能使用ActionLink()或RouteLink()来实现这一目标?

c# asp.net-mvc asp.net-mvc-5 html-helper
1个回答
1
投票

已有一个RouteLink()扩展方法,您可以使用它。您传递链接文本和路径定义的名称,以及参数的对象(或RouteValueDictionary),它将生成正确的href属性。在你的情况下,为Tenant路线

@Html.RouteLink("...", "Tenant", new { tenantId = 150, action = "Dashboard" })

生成.../Tenants/150/Dashboard

而对于TenantLocation

@Html.RouteLink("...", "TenantLocation", new { tenantId = 150, locationId = 300, controller = "Team", action = "Edit", id = 1000 })

生成../Tenants/150/Locations/300/Team/Edit/1000

© www.soinside.com 2019 - 2024. All rights reserved.