web-dev-qa-db-fra.com

Appelez UrlHelper dans les modèles dans ASP.NET MVC

J'ai besoin de générer des URL dans un modèle dans ASP.NET MVC. Je voudrais appeler quelque chose comme UrlHelper.Action () qui utilise les routes pour générer l'URL. Cela ne me dérange pas de remplir les blancs habituels, comme le nom d’hôte, le schéma, etc.

Y at-il une méthode que je peux appeler pour cela? Existe-t-il un moyen de construire un UrlHelper?

154
pupeno

J'aime la réponse d'Omar mais cela ne fonctionne pas pour moi. Pour mémoire, voici la solution que j'utilise maintenant:

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);
64
pupeno

Conseil utile, dans n'importe quelle application ASP.NET, vous pouvez obtenir une référence du HttpContext actuel.

HttpContext.Current

qui est dérivé de System.Web. Par conséquent, les éléments suivants fonctionneront n'importe où dans une application ASP.NET MVC:

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

Exemple:

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

L'appel de la propriété Link sur un objet MyModel créé renverra l'URL valide pour afficher le modèle en fonction du routage dans Global.asax.

274
Omar

Un UrlHelper peut être construit à partir d'une action de contrôleur avec les éléments suivants:

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

En dehors d'un contrôleur, un UrlHelper peut être construit en créant un RequestContext à partir de RouteTable.Routes RouteData.

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

(Basé sur la réponse de Brian, avec une correction de code mineure ajoutée.)

43
Nathan Taylor

Oui, vous pouvez l'instancier. Vous pouvez faire quelque chose comme:

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

RouteTable.Routes est une propriété statique, vous devriez donc être OK ici; pour obtenir une référence HttpContextBase, HttpContextWrapper prend une référence à HttpContext, et HttpContext le fournit.

8
Brian Mains

Après avoir essayé toutes les autres réponses, je me suis retrouvé avec

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

Les haineux vont détester ¯\_ (ツ) _/¯

2
Florian Winter

J'essayais de faire quelque chose de similaire depuis une page (en dehors d'un contrôleur).

UrlHelper ne m'a pas permis de le construire aussi facilement que Pablos répond, mais je me suis alors rappelé un vieux truc pour faire la même chose:

string ResolveUrl(string pathWithTilde)
0
vGHazard