2009-05-18 11 views
1

nous avons ce problème avec un contrôleur en ce moment; le contrôleur ressemble à ceci:ASP.NET MVC - Le paramètre du contrôleur n'est pas collecté à partir du formulaire?

public class AccountsController:Controller { 
    public ActionResult List(int? page, int? pageSize, string keywords) {...} 
} 

Nous affichons sur cette page via jquery:

$.post("/myapp/Accounts/List", 
     {"page":0,"pageSize":10,"keywords":"asdf"}, 
     updategrid, 
     "json"); 
... 
function updategrid(result) {...} 

Dans l'action: Request.Form [ "mots-clés"] == "asdf", mais les mots clés = = "" et ici je suis à perte. Pourquoi les mots clés n'ont-ils pas la valeur que nous voulons?

+0

En utilisant la réponse I fournie ci-dessous, mais pas satisfait de la syntaxe résultante. Cela ne me semble pas être la bonne façon de le faire. –

+3

Comment votre contrôleur est-il instancié? J'ai rencontré ce problème et j'ai trouvé que c'était SpringControllerFactory qui créait mes contrôleurs sous forme de singletons (et utilisait donc toujours les valeurs de la première requête). –

+0

C'est tout! Mon contrôleur a été enregistré en tant que singleton dans mon conteneur Windsor et mon WindsorControllerFactory a renvoyé un singleton. –

Répondre

1

citant réponse fournie comme commentaire de Mark Worth ...

Comment votre contrôleur étant instancié? J'ai eu ce problème et je trouvé que c'était mon SpringControllerFactory créant mes contrôleurs comme singletons (et donc utilisait toujours les valeurs de la première demande ). - Mark Worth 19 mai au 8:19

C'est tout! Mon contrôleur était enregistré comme un singleton dans mon conteneur Windsor alors mon WindsorControllerFactory a renvoyé un singleton . - Bill Barry 19 mai à 18:14

0

Dont vous voulez transmettre les valeurs de l'URL et de laisser le routage de MVC prendre soin de passer les valeurs? Ne pas passer en tant que variables réelles?

+0

Peut-être que j'aurais dû être plus clair: pageSize est définitivement passé (dans l'action il a la valeur attendue de 10) J'envoie les arguments dans le cadre d'un poste de formulaire. MVC prend soin de déplacer toutes mes valeurs du formulaire dans les arguments de la méthode, à l'exception de cette valeur de chaîne. –

+0

Voulez-vous vérifier le routage pour cette action particulière – CSharpAtl

+0

pouvez-vous afficher vos itinéraires enregistrés? – CSharpAtl

0

Si vous envoyez des messages les valeurs, vous pouvez simplement utiliser un FormCollection ..

public class AccountsController:Controller { 
public ActionResult List(int? page, FormCollection collection) { 

    string keywords=collection["keywords"]; 
    .... 
} 

}

En outre, pour le poste, vous pouvez ajouter l'identifiant à l'URL et de mettre les autres params en json. Je ne pense pas aussi qu'il est nécessaire de mettre vos noms de propriété entre guillemets dans JSON ..

$.post("/myapp/Accounts/List/"+page, 
    {pageSize:10,keywords:"asdf"}, 
    updategrid, 
    "json"); 

... fonction updategrid (résultat) {...}

... ou autres suggéré, vous pouvez créer un itinéraire qui a tous les paramètres possibles ..

+0

Je pourrais, mais je voudrais m'éloigner des cordes magiques si je peux. Le message jquery sera généré à partir d'une expression qui prétend appeler le contrôleur. –

+0

Vous ne savez pas ce que vous entendez par «chaînes magiques» et faire semblant d'appeler le contrôleur .. pourriez-vous expliquer? – markt

+0

Les chaînes magiques sont des chaînes qui représentent réellement du code, mais qui ne sont pas compilées (elles sont plutôt évaluées au moment de l'exécution). Au lieu de cela, je peux "faire semblant" d'appeler l'action dans mes vues afin de générer des liens avec une commande comme <% = LinkToActions.RenderJQueryPostJson (c => c.List (0,10, "asdf"), " updategrid ")%> La méthode prend un arbre d'expression et génère le javascript nécessaire dans ma vue.Pour ce faire, j'évite les erreurs d'exécution provoquées par des choses telles que le changement de nom des paramètres dans l'action (ou l'ajout de nouveaux paramètres car mes vues ne seront pas compilées). –

0

en utilisant cet attribut:

[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)] 
public class StringParamFilterAttribute:ActionFilterAttribute { 
    public string Param { get; set; } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) { 
     filterContext.ActionParameters[Param] = filterContext.HttpContext.Request[Param]; 
    } 
} 

j'ai pu mettre un attribut sur l'action pour donner ce paramètre à la méthode:

[StringParamFilter(Param="keywords")] 
public ActionResult List(int? page, int? pageSize, string keywords) {...} 

et mots-clés a maintenant la valeur souhaitée

+0

Maintenant que je l'ai fonctionné, la seule question qui me reste est pourquoi est-ce comme ça (il semble que tout autre que les chaînes seront récupérées)? –

+0

Je comprends que cela fonctionne pour vous, mais il ne semble pas juste ... – Gidon

+0

Je suis avec Gidon .... quelque chose semble étrange à propos de cette "solution" – CSharpAtl

0

Depuis l'attribut spécifié ci-dessus fonctionne, avez-vous vérifié pour comparer le contenu de la collection de HttpContext.Request.Form contre le MVC -Binder-Bound Objet FormCollection. On dirait qu'il y a une différence entre les deux ensembles. En outre, essayez d'autres moyens d'accéder à FormCollection - Get(), GetValue() ... cochez AllKeys pour la clé qui vous intéresse ???

En outre, en ce qui concerne l'idée d'itinéraire inscrire ...

Si vous ne possédez pas la route myApp/Comptes/Liste/{page}/{} pageSize enregistré et le pagesize est encore à venir à travers , il va de soi qu'il n'y a pas besoin d'enregistrer un itinéraire myApp/Comptes/Liste/{page}/{pageSize}/{} mots clés soit.

0

qui est très étrange, parce que le code sur ma machine fonctionne. Qu'est-ce qui se passe lorsque vous demandez l'URL directement depuis un navigateur (sans l'appel .post() jQuery) comme ceci:

/myapp/Accounts/List?page=0&pageSize=10&keywords=asdf 

qui génère une requête GET (au lieu de la requête POST générée par le .post jQuery() méthode - mais les paramètres de la méthode d'action doivent néanmoins être renseignés).

Aux fins de débogage, vous pouvez changer votre méthode d'action à quelque chose comme:

public ActionResult List(int? page, int? pageSize, string keywords) 
{ 
    return Content(String.Format("page = {0}, pageSize = {1}, keywords = {2}", 
        page, pageSize, keywords)); 
} 

Si cela fonctionne, l'étape suivante serait de tester votre appel jQuery avec quelque chose comme (changer le revenu format de données de JSON au texte):

$.post('/myapp/Accounts/List', 
     { 'page' : 0, 'pageSize' : 10, 'keywords' : 'asdf' }, 
     function(result) { 
      alert(result); 
     }, 
     'text'); 

Tout a fonctionné correctement ci-dessus pour moi, donc à moins que je manque quelque chose ... Je suis perplexe pourquoi ça n'a pas marché pour vous? Où est-ce que je me suis trompé?

0
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = false)] 
    public class JsonParametersFilter : ActionFilterAttribute 
    { 
     public override void OnActionExecuting(ActionExecutingContext filterContext) 
     { 
      string contentType = filterContext.HttpContext.Request.ContentType; 

      if (string.IsNullOrEmpty(contentType)) 
       return; 

      if (!contentType.Contains("application/json")) 
       return; 

      string paramValue; 

      using (var reader = new StreamReader(filterContext.HttpContext.Request.InputStream)) 
       paramValue = reader.ReadToEnd(); 

      var serializer = new JavaScriptSerializer(); 
      var rawResult = (IDictionary<string, object>)serializer.DeserializeObject(paramValue); 

      var keys = new List<string>(filterContext.ActionParameters.Keys); 

      foreach (var key in keys) 
      { 
       object value = null; 

       if (rawResult.TryGetValue(key, out value)) 
       { 
        filterContext.ActionParameters[key] = value; 
       } 
      } 
     } 
    } 

Ceci tentera de remplir toutes les valeurs de paramètres à partir de l'entrée.

Questions connexes