2009-09-18 11 views
162

in einer ASP.NET-Ansicht Normalerweise man die folgende Funktion eine URL verwenden könnte (keine <a>) zu erhalten:generiert URL in HTML-Hilfs

Url.Action("Action", "Controller"); 

aber ich kann nicht finden, wie es von einer Gewohnheit zu tun HTML-Helfer. Ich habe

public class MyCustomHelper 
{ 
    public static string ExtensionMethod(this HtmlHelper helper) 
    { 
    } 
} 

Die Helfer Variable, um die Aktion und GenerateLink Methoden, aber sie erzeugen <a> ‚s. Ich habe etwas im ASP.NET MVC Quellcode gegraben, aber ich konnte keinen direkten Weg finden.

Das Problem ist, dass die URL oben ein Mitglied der View-Klasse ist und für ihre Instantiierung einige Kontexte und Routenkarten benötigt (mit denen ich mich nicht befassen will und die ich sowieso nicht sollte). Alternativ hat die Instanz der HtmlHelper-Klasse auch einen Kontext, von dem ich anspreche, dass er entweder ein Supper einer Teilmenge der Kontextinformationen der Url-Instanz ist (aber ich möchte das auch nicht behandeln).

Zusammenfassend denke ich, dass es möglich ist, aber da alle Möglichkeiten, die ich sehen könnte, eine Manipulation mit mehr oder weniger internen ASP.NET-Sachen beinhalten, frage ich mich, ob es einen besseren Weg gibt.

Edit: Zum Beispiel ich eine Möglichkeit sehen wäre:

public class MyCustomHelper 
{ 
    public static string ExtensionMethod(this HtmlHelper helper) 
    { 
     UrlHelper urlHelper = new UrlHelper(helper.ViewContext.RequestContext); 
     urlHelper.Action("Action", "Controller"); 
    } 
} 

Aber es scheint nicht richtig. Ich möchte mich nicht mit Instanzen von UrlHelper befassen. Es muss einen leichteren Weg geben.

+3

Ich weiß, dies ist ein vereinfachtes Beispiel, aber für das Beispiel würde ich UrlHelper statt HtmlHelper erweitern. Ihr richtiger Code benötigt jedoch möglicherweise beide. –

+0

Entschuldigung, ich hätte klarer sein sollen: Ich wollte etwas HTML-Rendering in der Erweiterungsmethode machen und ich musste URLs dafür generieren. –

Antwort

206

Sie können url Helfer wie diese in HTML-Helfer-Extension-Methode erstellen:

var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext); 
var url = urlHelper.Action("Home", "Index") 
+0

Ah, danke. Ich habe gerade das gleiche gepostet :-) –

+2

Ich denke, dass es besser wäre, wenn der Konstruktor auch RouteCollection 'new UrlHelper (htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection) initialisieren würde' – kpull1

21

Sie auch Links mit UrlHelper öffentlichen und statische Klasse erhalten können:

UrlHelper.GenerateUrl(null, actionName, controllerName, null, null, null, routeValues, htmlHelper.RouteCollection, htmlHelper.ViewContext.RequestContext, true) 

Sie nicht in diesem Beispiel Ich muss eine neue UrlHelper-Klasse erstellen, was ein kleiner Vorteil sein könnte.

+0

Ich mag diese Antwort mehr, weil die RouteCollection setzt. – kpull1

9

Hier ist meine kleine extenstion Methode für UrlHelper eine HtmlHelper Instanz bekommen:

public static partial class UrlHelperExtensions 
    { 
     /// <summary> 
     /// Gets UrlHelper for the HtmlHelper. 
     /// </summary> 
     /// <param name="htmlHelper">The HTML helper.</param> 
     /// <returns></returns> 
     public static UrlHelper UrlHelper(this HtmlHelper htmlHelper) 
     { 
      if (htmlHelper.ViewContext.Controller is Controller) 
       return ((Controller)htmlHelper.ViewContext.Controller).Url; 

      const string itemKey = "HtmlHelper_UrlHelper"; 

      if (htmlHelper.ViewContext.HttpContext.Items[itemKey] == null) 
       htmlHelper.ViewContext.HttpContext.Items[itemKey] = new UrlHelper(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection); 

      return (UrlHelper)htmlHelper.ViewContext.HttpContext.Items[itemKey]; 
     } 
    } 

Verwenden Sie es als:

public static MvcHtmlString RenderManagePrintLink(this HtmlHelper helper,) 
{  
    var url = htmlHelper.UrlHelper().RouteUrl('routeName'); 
    //... 
} 

(Ich bin dieses Posting als Referenz am nur)

+0

Hervorragender Ansatz, da ein vorhandenes Objekt wiederverwendet wird, anstatt ein neues Objekt zu erstellen. – Mike