在HtmlHelper扩展方法中附加到routeValues

时间:2012-02-03 14:35:38

标签: asp.net-mvc asp.net-mvc-3 html-helper

我想创建一个HtmlHelper.ActionLink的简单扩展,为路由值字典添加一个值。参数与HtmlHelper.ActionLink相同,即:

public static MvcHtmlString FooableActionLink(
    this HtmlHelper html,
    string linkText,
    string actionName,
    string controllerName,
    object routeValues,
    object htmlAttributes)
{
  // Add a value to routeValues (based on Session, current Request Url, etc.)
  // object newRouteValues = AddStuffTo(routeValues);

  // Call the default implementation.
  return html.ActionLink(
      linkText, 
      actionName, 
      controllerName, 
      newRouteValues, 
      htmlAttributes);
}

我添加到routeValues的逻辑有点冗长,因此我希望将它放在扩展方法助手中,而不是在每个视图中重复它。

我有一个似乎有效的解决方案(在下面发布作为答案),但是:

  • 对于这么简单的任务来说,这似乎是不必要的复杂。
  • 所有的施法都让我感到脆弱,就像有一些边缘情况,我将会导致NullReferenceException等。

请发布任何改进建议或更好的解决方案。

1 个答案:

答案 0 :(得分:12)

public static MvcHtmlString FooableActionLink(
    this HtmlHelper html,
    string linkText,
    string actionName,
    string controllerName,
    object routeValues,
    object htmlAttributes)
{
    // Convert the routeValues to something we can modify.
    var routeValuesLocal =
        routeValues as IDictionary<string, object>
        ?? new RouteValueDictionary(routeValues);

    // Convert the htmlAttributes to IDictionary<string, object>
    // so we can get the correct ActionLink overload.
    IDictionary<string, object> htmlAttributesLocal =
        htmlAttributes as IDictionary<string, object>
        ?? new RouteValueDictionary(htmlAttributes);

    // Add our values.
    routeValuesLocal.Add("foo", "bar");

    // Call the correct ActionLink overload so it converts the
    // routeValues and htmlAttributes correctly and doesn't 
    // simply treat them as System.Object.
    return html.ActionLink(
        linkText,
        actionName,
        controllerName,
        new RouteValueDictionary(routeValuesLocal),
        htmlAttributesLocal);
}