2012-02-03 12 views
6

Chcę utworzyć proste rozszerzenie HtmlHelper.ActionLink, które dodaje wartość do słownika wartości trasy. Parametry byłby identyczny HtmlHelper.ActionLink, tj .:Dołącz do routeValues ​​w metodzie rozszerzenia HtmlHelper

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); 
} 

Logika co dodaję do routeValues jest nieco rozwlekły, stąd moje pragnienie, aby umieścić go w metodę rozszerzenia pomocnika zamiast powtarzać to w każdym widoku.

Mam rozwiązanie, które wydaje się działać (Wysłany jako odpowiedź poniżej), ale:

  • Wydaje się być niepotrzebnie skomplikowane dla tak prostego zadania.
  • Cała operacja uderza mnie jako delikatną, tak jak w niektórych przypadkach, gdzie zamierzam wywołać wyjątek NullReferenceException lub coś podobnego.

Zamieszczaj wszelkie sugestie dotyczące ulepszeń lub lepszych rozwiązań.

Odpowiedz

10
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); 
} 
+0

Jeśli jesteś zainteresowany, mam pytanie to pytanie, które jest związane z tej odpowiedzi: http://stackoverflow.com/questions/9595334/correctly-making-an-actionlink-extension-with-htmlattributes –