2010-01-09 8 views
148

Ich muss einige URLs in einem Modell in ASP.NET MVC generieren. Ich möchte etwas wie UrlHelper.Action() aufrufen, das die Routen verwendet, um die URL zu generieren. Es macht mir nichts aus, die üblichen Lücken zu füllen, wie den Hostnamen, das Schema und so weiter.Call UrlHelper in Modellen in ASP.NET MVC

Gibt es irgendeine Methode, die ich dafür verlangen kann? Gibt es eine Möglichkeit, einen UrlHelper zu erstellen?

+1

ich darüber selbst dachte, aber beachten Sie, dass Url.Action eine relative URL generieren. Seien Sie sicher, dass Sie das wollen. –

Antwort

62

Ich mag Omars Antwort, aber das funktioniert nicht für mich. Nur für das Protokoll ist dies die Lösung, die ich jetzt bin mit:

var httpContext = HttpContext.Current; 

if (httpContext == null) { 
    var request = new HttpRequest("/", "http://example.com", ""); 
    var response = new HttpResponse(new StringWriter()); 
    httpContext = new HttpContext(request, response); 
} 

var httpContextBase = new HttpContextWrapper(httpContext); 
var routeData = new RouteData(); 
var requestContext = new RequestContext(httpContextBase, routeData); 

return new UrlHelper(requestContext); 
+1

Was ist Config.Url? – joshcomley

+0

Es enthält die URL meiner Website. Dort habe ich es entfernt. – Pablo

+2

Wenn Sie berücksichtigen, dass die UrlHelper-Klasse vom Anforderungskontext (und vom HTTP-Kontext) abhängt, kann das manuelle Erstellen dieser Kontextobjekte zu unerwarteten Ergebnissen führen. Wenn HttpContext.Current null ist und Sie diesen Ansatz verwenden, würde ich mit Vorsicht vorgehen. – Sean

-27

Ich denke, was Sie suchen ist dies:

Url.Action("ActionName", "ControllerName"); 
41

A UrlHelper kann innerhalb einer Controller-Aktion mit der folgenden konstruiert werden:

var url = new UrlHelper(this.ControllerContext.RequestContext); 
url.Action(...); 

Außerhalb eines Controllers, eines UrlHelper kann durch Erstellen eines RequestContext aus RouteTable.Routes RouteData erstellt werden.

HttpContextWrapper httpContextWrapper = new HttpContextWrapper(System.Web.HttpContext.Current); 
UrlHelper urlHelper = new UrlHelper(new RequestContext(httpContextWrapper, RouteTable.Routes.GetRouteData(httpContextWrapper))); 

(Basierend auf Brians Antwort, mit einer kleineren Codekorrektur hinzugefügt.)

+1

Aber ich habe keinen Controller im Modell. – Pablo

+0

Okay, ich entschuldige mich, ich war mir nicht sicher, wo genau der Code ausgeführt wurde. Lassen Sie mich einen Blick darauf werfen ... –

+2

Keine Notwendigkeit, einen neuen Anfragekontext zu erstellen: 'var urlHelper = neue UrlHelper (HttpContext.Current.Request.RequestContext);' – bradlis7

8

Ja, Sie es instanziieren. Sie können so etwas wie tun:

var ctx = new HttpContextWrapper(HttpContext.Current); 
UrlHelper helper = new UrlHelper(
    new RequestContext(ctx, 
    RouteTable.Routes.GetRouteData(ctx)); 

RouteTable.Routes ist eine statische Eigenschaft, so dass Sie es in Ordnung sein sollte; Um eine HttpContextBase Referenz zu erhalten, HttpContextWrapper nimmt einen Verweis auf HttpContext, und HttpContext liefert das.

+0

Das wird nicht funktionieren, obwohl es sehr nah ist. Siehe meine Antwort unten. –

261

Hilfreicher Tipp in jeder ASP.NET-Anwendung, können Sie einen Verweis auf das aktuelle Httpcontext erhalten

HttpContext.Current 

, die von System.Web abgeleitet ist. Daher wird die folgende Arbeit überall in einer ASP.NET MVC-Anwendung:

UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext); 
url.Action("ContactUs"); // Will output the proper link according to routing info 

Beispiel:

public class MyModel 
{ 
    public int ID { get; private set; } 
    public string Link 
    { 
     get 
     { 
      UrlHelper url = new UrlHelper(HttpContext.Current.Request.RequestContext); 
      return url.Action("ViewAction", "MyModelController", new { id = this.ID }); 
     } 
    } 

    public MyModel(int id) 
    { 
     this.ID = id; 
    } 
} 

aufrufen Link Eigenschaft auf einem erstellten MyModel Objekt wird die gültige URL senden Sie das Modell zu betrachten, basierend auf dem Routing in Global.asax

+0

Sind Sie sicher, dass ein HttpContext.Current.Request.RequestContext vorhanden ist? HttpContext.Current.Request scheint keinen RequestContext zu haben. – Pablo

+1

Das ist seltsam. Ich habe gerade diese Lösung getestet und es funktioniert perfekt. Ich führe ASP.NET MVC 2 Preview 2, aber ich denke, das funktioniert über alle Versionen hinweg. Nicht sicher, warum es nicht für dich arbeitet. Erstellen Sie die Klasse außerhalb eines MVC-Projekts? Stellen Sie außerdem sicher, dass es 'using' für' System.Web' und 'System.Web.Mvc' gibt. – Omar

+0

Ich bin auf einem ASP.NET MVC 1 Projekt, ich dachte über vermisste usings aber ich habe beide von ihnen. – Pablo

0

Ich habe versucht, etwas Ähnliches aus innerhalb einer Seite (außerhalb eines Controllers) zu tun.

UrlHelper nicht gestatten Sie mir, es zu konstruieren, so leicht wie Pablos Antwort, aber dann erinnerte ich mich an einen alten Trick, um effektiv das gleiche tun:

string ResolveUrl(string pathWithTilde) 
0

Nachdem alle anderen Antworten versuchen, landete ich mit

@"/api/Things/Action/{id}" 

Haters Gonna Hass ¯ \ _ (ツ) _/¯