如何将哈希片段添加到 T4MVC 路由字典 ActionResult 中?
我有一个返回 ActionResult 的扩展方法(出于演示目的而简化):
public static ActionResult GetTestActionResult(this HtmlHelper htmlHelper, int productId)
{
return MVC.Products.Details(productId);
}
我在 Html.ActionLink 中使用它:
@Html.ActionLink("Product Details", Html.GetTestActionResult(Model.ProductId), new { @class = "button blue" });
我正在使用选项卡的自定义 jQuery 插件,该插件使用这些哈希片段进行导航。我想通过将哈希片段标记到 URL 的末尾来添加我想要打开的选项卡。
Html.ActionLink 确实有一个重载 对于 Fragment,即:
public static MvcHtmlString ActionLink(
this HtmlHelper htmlHelper,
string linkText,
string actionName,
string controllerName,
string protocol,
string hostName,
string fragment,
Object routeValues,
Object htmlAttributes
)
然而,它充满了令人讨厌的魔法字符串,T4MVC 旨在将其删除。无论如何,是否可以在我的静态扩展方法(GetTestActionResult)中将片段添加到路由字典中?
比如:
return MVC.Products.Details(productId).AddRouteValue(String.Empty, "#tab-similar-products");
我知道 SO 上有两个类似的问题和答案,但它们并没有完全为我提供我正在寻找的东西。我需要将片段包装到 ActionResult 中,然后再将其传回视图:
更新:
使用David Ebbo 的修复如下,我做了以下更改。有点 hacky,但它有效:
首先,我更改了返回 ActionResult 的内部函数,以便它还将片段添加为路由值(不理想但有效):
return MVC.Products.Details(productId).AddRouteValue("tab", "#tab-similar-products");
然后在视图中,它将该片段值复制到路由之外字典,然后删除该路由值以确保完整性。
// get my ActionResult with the tab fragment tagged on as a route value
var actionResult = Html.GetTestActionResult(item.Key, Model.ClaimId);
// get the tab fragment value
var tabRoute = actionResult.GetRouteValueDictionary().FirstOrDefault(r => r.Key == "tab").Value ?? "none";
// remove the route value, otherwise it will get tagged to the querystring
actionResult.GetRouteValueDictionary().Remove("tab");
// display
@Html.ActionLink("Product Details", Html.GetTestActionResult(Model.ProductId), new { @class = "button blue" }, fragment: tabRoute.ToString());
我确信有一种更漂亮的方法可以用 ActionResult 返回片段,但目前这是可行的。谢谢大卫。
I have an extension method that returns an ActionResult (simplified for demonstration purposes):
public static ActionResult GetTestActionResult(this HtmlHelper htmlHelper, int productId)
{
return MVC.Products.Details(productId);
}
I'm using this in an Html.ActionLink:
@Html.ActionLink("Product Details", Html.GetTestActionResult(Model.ProductId), new { @class = "button blue" });
I'm using a custom jQuery plugin for tabs, that uses these hash fragments for navigation. I want to add the tab which I want to open, by tagging the hash fragment onto the end of the URL.
Html.ActionLink does have an overload for the Fragment, namely:
public static MvcHtmlString ActionLink(
this HtmlHelper htmlHelper,
string linkText,
string actionName,
string controllerName,
string protocol,
string hostName,
string fragment,
Object routeValues,
Object htmlAttributes
)
However, that is full of nasty magic strings, which T4MVC is designed to remove. Is there anyway to add the fragment to the route dictionary in my static extension method (GetTestActionResult)?
Something like:
return MVC.Products.Details(productId).AddRouteValue(String.Empty, "#tab-similar-products");
I am aware that there are two similar questions and answers on SO, but they don't quite provide me with what I am looking for. I need to wrap the fragment into the ActionResult BEFORE passing it back to the view:
UPDATE:
Using David Ebbo's fix below, I made the following changes. A bit hacky, but it works:
First I altered my internal function that returns an ActionResult so that it would also add the fragment as a route value (not ideal but works):
return MVC.Products.Details(productId).AddRouteValue("tab", "#tab-similar-products");
Then in the view it copies that fragment value out of the route dictionary, then removes that route value for completeness.
// get my ActionResult with the tab fragment tagged on as a route value
var actionResult = Html.GetTestActionResult(item.Key, Model.ClaimId);
// get the tab fragment value
var tabRoute = actionResult.GetRouteValueDictionary().FirstOrDefault(r => r.Key == "tab").Value ?? "none";
// remove the route value, otherwise it will get tagged to the querystring
actionResult.GetRouteValueDictionary().Remove("tab");
// display
@Html.ActionLink("Product Details", Html.GetTestActionResult(Model.ProductId), new { @class = "button blue" }, fragment: tabRoute.ToString());
I'm sure there is a prettier way to return the fragment with the ActionResult, but for the moment this works. Thanks David.
T4MVC 需要新的重载来处理这个问题。在 T4MVC.tt 中,尝试更改:
然后
您将能够编写类似以下内容的内容:
让我知道这是否有效,我会尝试将其添加到主模板中。
T4MVC needs new overloads to handle this. In T4MVC.tt, try changing:
to
you'll then be able to write something like:
Let me know if that works, and I'll try to get it added to the main template.