2010-08-11 6 views
9
<% using (Html.BeginForm("SubmitUserName")) { %> 
    <input type='text' name='user-name' /> 
    <input type='submit' value='Send' /> 
<% } %> 

Quelle devrait être la signature d'une méthode d'action correspondante pour accepter le paramètre user-name?Utilisation d'un tiret (-) dans les paramètres ASP.MVC

public ActionResult SubmitUserName(string user-name) {...} 

signature de la méthode ci-dessus fonctionne pas pour une raison quelconque ;-)

Je sais qu'il ya un ActionNameAttribute pour gérer la situation avec un tiret nom d'action. Y at-il quelque chose comme ParameterNameAttribute?

+0

Avez-vous vraiment besoin d'utiliser tableau de bord? –

+0

est-il ** requis ** d'être 'nom d'utilisateur'? – Buildstarted

+0

Ce n'est pas obligatoire du tout. Il est juste curieux que MVC n'ait pas pensé à ce scénario. Je ne l'utilise pas vraiment, juste curieux si c'est là ... ou pourquoi il n'est pas là. –

Répondre

12

Comme tout le monde l'a noté, le plus facile solution serait de ne pas utilise un tiret. Si vous avez vraiment besoin du tiret, vous pouvez créer votre propre ActionFilterAttribute pour le gérer.

Quelque chose comme:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] 
public class ParameterNameAttribute : ActionFilterAttribute 
{ 
    public string ViewParameterName { get; set; } 
    public string ActionParameterName { get; set; } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     if(filterContext.ActionParameters.ContainsKey(ViewParameterName)) 
     { 
      var parameterValue = filterContext.ActionParameters[ViewParameterName]; 
      filterContext.ActionParameters.Add(ActionParameterName, parameterValue); 
     } 
    } 
} 

Vous pouvez ensuite appliquer le filtre à la méthode d'action appropriée:

[ParameterName(ViewParameterName = "user-data", ActionParameterName = "userData")] 
[ParameterName(ViewParameterName = "my-data", ActionParameterName = "myData")] 
    public ActionResult About(string userData, string myData) 
    { 
     return View(); 
    } 

Vous auriez probablement eu envie d'améliorer la ParameterNameAttribute pour gérer les majuscules/minuscules, mais serait l'idée de base.

+0

Cela ne fonctionnait pas pour moi dans MVC 4, –

+0

de ProVega 'OnActionExecuting' devrait utiliser' TryGetValue' pour éviter la double recherche de 'ContainsKey' suivi de l'indexeur. –

0

Je vous conseille de faire quelque chose comme ça - à moins qu'il ne doit utiliser l'attribut user-name (ou que vous n'êtes pas se lier à un modèle)

<% using (Html.BeginForm("SubmitUserName")) { %> 
    <%: Html.TextBoxFor(m => m.UserName) %> 
    <input type='submit' value='Send' /> 
<% } %> 
3

J'ai trouvé cette réponse utile, mais je ne sais pas exactement comment l'exemple fourni est utile. Il semble simplement "renommer" une valeur que le classeur a déjà fourni. Dans mon cas, j'étais posté par un service externe qui publiait quelque chose comme "body-plain" et je ne pouvais pas contrôler le nom. Donc, j'ai modifié cet exemple pour ressembler à ceci:

[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] 
public class ParameterNameMapAttribute : ActionFilterAttribute 
{ 
    public string InboundParameterName { get; set; } 
    public string ActionParameterName { get; set; } 

    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     object value = filterContext.RequestContext.HttpContext.Request[InboundParameterName]; 

     if (filterContext.ActionParameters.ContainsKey(ActionParameterName)) 
     { 
      filterContext.ActionParameters[ActionParameterName] = value; 
     } 
     else 
     { 
      throw new Exception("Parameter not found on controller: " + ActionParameterName); 
     } 
    } 
} 

Cela prend effectivement dans le paramètre « corps simple » par exemple et cartes à un actionParameter je définissais sur mon contrôleur. Comme si:

[ParameterNameMap(InboundParameterName = "body-plain", ActionParameterName = "bodyPlainText")] 
    [ParameterNameMap(InboundParameterName = "Thread-Topic", ActionParameterName = "alternateSubject")] 
    public HttpStatusCodeResult Process(string token, string timestamp, string signature, string subject, string sender, string recipient, string bodyPlainText, string alternateSubject) 
    { 
10

Créer un pseudo-paramètre dans la première ligne de la méthode d'action:

public ActionResult SubmitUserName() 
{ 
    string userName = Request.Params["user-name"]; 
    ... 
} 
+0

Cela n'a même pas compilé pour moi. Parlez-vous d'ApiController? –

+0

Oh idiot, la question concerne MVC ... et je suis en train de faire l'API Web. Alors ok. –

+3

Cela a bien fonctionné pour moi dans MVC. Upvoted. – ChrisFox