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

應接受user-name參數的相應Action方法的簽名應該是什麼?在ASP.MVC參數中使用破折號( - )

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

方法簽名上面並沒有因爲某些原因;-)

我知道有一個ActionNameAttribute處理情況與動作名稱的衝刺工作。有沒有像ParameterNameAttribute

+0

你真的需要使用幾許? – 2010-08-11 18:04:55

+0

是否需要**才能成爲用戶名? – Buildstarted 2010-08-11 18:05:27

+0

根本不需要。令人費解的是MVC沒有想到這種情況。我實際上並沒有使用它,只是好奇它是否存在......或者它爲什麼不存在。 – 2010-08-11 19:06:51

回答

12

正如大家所指出的,在最簡單的解決方法是不再使用短劃線。如果你真的需要破折號,你可以創建自己的ActionFilterAttribute來處理它。

喜歡的東西:

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

你會再過濾器應用於適當的行動方法:

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

你可能會想要增強ParameterNameAttribute辦理大/小寫,但將是基本的想法。

+0

這在MVC 4中並不適用於我,ProVega的做法是 – 2014-01-08 01:52:38

+0

'OnActionExecuting'應該使用'TryGetValue'來避免'ContainsKey'跟索引器的雙重查找。 – 2016-04-13 13:02:10

0

我建議做這樣的事情 - 除非它需要使用user-name屬性(或者你不綁定到一個模型)

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

我發現這個答案有幫助,但我不確切知道如何提供的示例幫助。它似乎只是「重命名」一個已經準備好的資料夾。

在我的情況下,我被張貼到一個外部服務,將張貼像「body-plain」的東西,我無法控制名稱。所以我修改這個樣品看起來像這樣:

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

這實際上發生在參數「身體平原」爲例,它映射到我我的控制器上定義的ActionParameter。像這樣:

[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

在操作方法的第一行創建一個僞參數:

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

這甚至沒有爲我編譯。你在談論ApiController嗎? – 2014-01-11 18:06:01

+0

哦,我很傻,問題是關於MVC ......而我正在做Web API。好吧。 – 2014-01-11 18:14:38

+3

在MVC中,我工作得很好。 Upvoted。 – ChrisFox 2015-05-30 10:31:27