ASP.NET MVC QueryString par défaut substituant des valeurs fournies?
À l'aide de ASP.NET MVC Aperçu 5 (bien que cela a aussi été essayé avec la version Bêta), il semble que la chaîne de recherche par défaut dans un itinéraire remplacer la valeur qui est passée sur la chaîne de requête. Une repro est d'écrire un contrôleur comme ceci:
public class TestController : Controller
{
public ActionResult Foo(int x)
{
Trace.WriteLine(x);
Trace.WriteLine(this.HttpContext.Request.QueryString["x"]);
return new EmptyResult();
}
}
Avec de l'itinéraire tracé comme suit:
routes.MapRoute(
"test",
"Test/Foo",
new { controller = "Test", action = "Foo", x = 1 });
Et puis l'invoquer à cette URI relatif:
/Test/Foo?x=5
La sortie de trace je vois, c'est:
1
5
Donc, en d'autres mots, la valeur par défaut qui a été mis en place pour l'itinéraire est toujours passé dans la méthode, indépendamment de savoir si elle a été effectivement fournis dans la chaîne de requête. Notez que si la valeur par défaut de la chaîne de requête est supprimée, c'est à dire le chemin est tracé comme suit:
routes.MapRoute(
"test",
"Test/Foo",
new { controller = "Test", action = "Foo" });
Le régulateur se comporte comme prévu et la valeur est transmise en tant que paramètre de valeur, donnant à la sortie de trace:
5
5
Cela ressemble pour moi comme un bug, mais je pense qu'il serait très surprenant qu'un bug comme celui-ci pourrait encore être dans la version bêta de l'ASP.NET framework MVC, comme querystrings avec les valeurs par défaut ne sont pas exactement ésotérique ou le bord de cas sur la fonctionnalité, de sorte qu'il est presque certainement de ma faute. Les idées de ce que je fais mal?
- Un débordement de pile a besoin d'un "vote vendeur en retard" bouton pour ces cas.
Vous devez vous connecter pour publier un commentaire.
La meilleure façon de le regarder ASP.NET MVC avec QueryStrings est de penser à eux comme à des valeurs que l'itinéraire ne sais pas. Comme vous l'avez constaté, l'QueryString ne fait pas partie de la RouteData, par conséquent, vous devez garder ce que vous êtes de passage comme une chaîne de requête distincte de la route des valeurs.
Un moyen de les contourner est de créer des valeurs par défaut vous-même dans l'action si les valeurs passées de la chaîne de Requête sont nulles.
Dans votre exemple, l'itinéraire sait à propos de x, donc votre url doit vraiment ressembler à ceci:
et de la route devrait ressembler à ceci:
Pour obtenir le comportement que vous recherchez.
Si vous souhaitez passer une QueryString valeur, disons comme un numéro de page puis vous le faire:
Et votre action doit modifier comme ceci:
Maintenant le test:
Espère que cela aide à clarifier certaines choses.
Un de mes collègues ont trouvé un lien qui indique que c'est par la conception et il semble que l'auteur de cet article soulevé un problème avec le MVC équipe avoir dit que c'était un changement de versions antérieures. La réponse est ci-dessous (pour "page", vous pouvez lire "x" pour se relier à la question ci-dessus):
Il semble donc que ce comportement est "correcte", cependant il est donc orthogonale à la principe de moindre étonnement que je n'arrive toujours pas à y croire.
Edit #1: Notez que le post détaille une méthode de la façon de fournir des valeurs par défaut, cependant cela ne fonctionne plus comme la
ActionMethod
biens qu'il utilise pour accéder à laMethodInfo
a été supprimé dans la version la plus récente de ASP.NET MVC. Je suis actuellement en train de travailler sur une alternative et affichera lorsque vous avez terminé.Edit #2: j'ai mis à jour l'idée dans le message lié à travailler avec l'Aperçu de la libération des 5 ASP.NET MVC et je crois que ça devrait aussi fonctionner avec la version Bêta si je ne peux pas garantir que nous n'avons pas déplacé à cet instant. C'est tellement simple que je viens de posté dans la ligne ici.
D'abord il y a l'attribut par défaut (on ne peut pas utiliser l'existant .NET
DefaultValueAttribute
comme il se doit hériter deCustomModelBinderAttribute
):Le la coutume de classeur:
Et alors vous pouvez simplement l'appliquer à la méthode de paramètres qui entrent dans la chaîne de requête, par exemple
Fonctionne comme un charme!
Je pense que la raison querystring paramètres de ne pas remplacer les valeurs par défaut est d'empêcher le piratage de l'url.
Quelqu'un pourrait utiliser une url dont le querystring inclus contrôleur, les actions ou autres valeurs par défaut vous n'avez pas envie de changer.
J'ai résolu ce problème en faisant ce que @Dale-Ragan proposé et de le traiter dans la méthode d'action. Fonctionne pour moi.
Je pense que le point avec le Routage dans MVC est de se débarrasser de querystrings. Comme ceci: