在HtmlHelper扩展方法中附加到routeValues

Dav*_*eer 7 asp.net-mvc html-helper asp.net-mvc-3

我想创建一个简单的扩展,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);
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 这样一个简单的任务似乎不必要地复杂化.
  • 所有的演员都让我觉得很脆弱,就像有一些边缘情况,我将会导致NullReferenceException等.

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

Dav*_*eer 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);
}
Run Code Online (Sandbox Code Playgroud)