41 votes

Comment passer Request.QueryString à Url.Action ?

Je suis en train de construire une url en utilisant la méthode :

Url.Action("action", "controller");

J'aime passer la chaîne de requête de la demande actuelle dans cette url également. Quelque chose comme ce qui suit (mais cela ne fonctionne pas) :

Url.Action("action", "controller", Request.QueryString);

La conversion du QueryString en valeurs de route est possible avec l'extension suivante :

    public static RouteValueDictionary ToRouteValues(this NameValueCollection queryString)
    {
        if (queryString.IsNull() || queryString.HasKeys() == false) return new RouteValueDictionary();

        var routeValues = new RouteValueDictionary();
        foreach (string key in queryString.AllKeys)
            routeValues.Add(key, queryString[key]);

        return routeValues;
    }

Avec la méthode de l'extension, ce qui suit fonctionne :

Url.Action("action", "controller", Request.QueryString.ToRouteValues());

Existe-t-il un autre moyen plus efficace ? Thx

35voto

pwhe23 Points 420

Si vous souhaitez pouvoir ajouter facilement des paramètres de valeur de route supplémentaires à votre Url.Action, essayez cette méthode d'extension (basée sur celle de Linefeed) qui prend un objet anonyme et renvoie une RouteValueCollection :

public static RouteValueDictionary ToRouteValues(this NameValueCollection col, Object obj)
{
    var values = new RouteValueDictionary(obj);
    if (col != null)
    {
        foreach (string key in col)
        {
            //values passed in object override those already in collection
            if (key != null && !values.ContainsKey(key)) values[key] = col[key];
        }
    }
    return values;
}

Vous pouvez alors l'utiliser comme suit :

Url.Action("action", "controller", Request.QueryString.ToRouteValues(new{ id=0 }));

14voto

Darin Dimitrov Points 528142

La méthode de l'extension semble correcte et est la voie à suivre.

2voto

Tomino Points 107

Voici ma solution basée sur la réponse de pwhe23. Je voulais garder les paramètres de la chaîne de requête pour les requêtes POST (à cause d'une grille Mvc) et utiliser une seule action pour les GET HTTP. Les actions CRUD sont gérées par une seule page et des dialogues modaux à l'intérieur (pour l'insertion/mise à jour/suppression).

Alors voici mon extension :

public static class MvcExtensions
{
    public static RouteValueDictionary ToRouteValues(this NameValueCollection col, Object obj = null)
    {
        var values = obj != null ? new RouteValueDictionary(obj) : new RouteValueDictionary();

        if (col == null) return values;

        foreach (string key in col)
        {
            //values passed in object are already in collection
            if (!values.ContainsKey(key)) values[key] = col[key];
        }
        return values;
    }
}

Utilisation dans le contrôleur (par exemple, action de modification) :

    [HttpPost]
    public ActionResult Edit(MyModel model)
    {
        // Some stuff
        return RedirectToAction("Index", Request.QueryString.ToRouteValues());
    }

Formulaire d'édition généré dans View (le dialogue modal est utilisé) :

 @using (Html.BeginForm("Edit", "SomeControllerName", Request.QueryString.ToRouteValues(), FormMethod.Post))
    {
        // Some stuff... e.g. dialog content
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X