【问题标题】:Using a dash (-) in ASP.MVC parameters在 ASP.MVC 参数中使用破折号 (-)
【发布时间】:2011-03-28 13:02:49
【问题描述】:
<% using (Html.BeginForm("SubmitUserName")) { %>
    <input type='text' name='user-name' />
    <input type='submit' value='Send' />
<% } %>

接受user-name参数的相应Action方法的签名应该是什么?

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

上面的方法签名由于某种原因不起作用;-)

我知道有一个ActionNameAttribute 来处理动作名称中带有破折号的情况。有ParameterNameAttribute之类的吗?

【问题讨论】:

  • 你真的需要使用dash吗?
  • user-name是否必须?
  • 根本不需要。令人费解的是,MVC 没有想到这种情况。我实际上并没有使用它,只是好奇它是否存在......或者为什么它不存在。
  • 存在使用第三方工具需要支持破折号的场景

标签: c# asp.net-mvc-2


【解决方案1】:

我建议做这样的事情 - 除非需要使用 user-name 属性(或者您没有绑定到模型)

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

【讨论】:

    【解决方案2】:

    正如大家所指出的,最简单的解决方法是不使用破折号。不过,如果您真的需要破折号,您可以创建自己的 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);   
            }
        }
    }
    

    然后您将过滤器应用到适当的 Action 方法:

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

    您可能希望增强 ParameterNameAttribute 以处理大写/小写,但这是基本思想。

    【讨论】:

    • OnActionExecuting 应使用TryGetValue 以避免重复查找ContainsKey 后跟索引器。
    【解决方案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);
            }
        }
    }
    

    这实际上以参数“body-plain”为例,并将其映射到我在控制器上定义的 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)
        {
    

    【讨论】:

      【解决方案4】:

      在action方法的第一行创建一个伪参数:

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

      【讨论】:

      • 这甚至没有为我编译。你说的是 ApiController 吗?
      • 哦,愚蠢的我,问题是关于 MVC 的......我正在做 Web API。那好吧。
      【解决方案5】:

      没有根据相关技术回答实际问题,但无论如何,世界在某些领域向前发展;在 AspNetCore.Mvc 中你可以简单地做:

          [HttpGet()]
          public ActionResult SubmitUserName( [FromHeader(Name = "user-Name")] string userName) {...}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-11-07
        • 2013-02-10
        • 2020-09-05
        • 2011-02-21
        • 2012-07-15
        • 1970-01-01
        • 2012-05-10
        相关资源
        最近更新 更多