MVC3中的多个提交按钮 - FormCollection没有输入类型提交的键/值 - 远程验证问题?

时间:2011-08-17 12:50:17

标签: asp.net-mvc asp.net-mvc-3

我在MVC3应用程序中有两个按钮。

   <input type="submit" name="command" value="Transactions" />  &nbsp;
   <input type="submit" name="command" value="All Transactions" />

当我点击一个按钮时,它会正确回发,但FormCollection没有“命令”键。我还在模型中添加了一个属性“command”,并且在发布表单时它的值为null。

public ActionResult Index(FormCollection formCollection, SearchReportsModel searchReportsModel).         {
            if (searchReportsModel.command == "All Transactions")
              ...
            else
              ....
        }

我正在使用IE8。如何在MVC3中使用多个按钮?这个问题有解决方法吗?我做了很多研究,找不到解决方案 更新:

Dave:我尝试了你的解决方案,它正在抛出Http 404错误“无法找到资源”。

这是我的代码:

[HttpPost]
[AcceptSubmitType(Name = "Command", Type = "Transactions")]
public ActionResult Index(SearchReportsModel searchReportsModel)
{
    return RedirectToAction("Transactions", "Reports", new { ...});
}

[HttpPost]
[ActionName("Index")]
[AcceptSubmitType(Name = "Command", Type = "All Transactions")]
public ActionResult Index_All(SearchReportsModel searchReportsModel)
{
   return RedirectToAction("AllTransactions", "Reports", new { ... });
}

public class AcceptSubmitTypeAttribute : ActionMethodSelectorAttribute
    {
        public string Name { get; set; }
        public string Type { get; set; }

        public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
        {
            return controllerContext.RequestContext.HttpContext
                .Request.Form[this.Name] == this.Type;
        }
    }

在ViewModel(SearchReportsModel)中评论以下远程验证属性后,问题得以解决。看起来它是MVC3中的一个错误:

  //[Remote("CheckStudentNumber", "SearchReports", ErrorMessage = "No records exist for this Student Number")]
  public int? StudentNumber { get; set; }

5 个答案:

答案 0 :(得分:5)

您可以使用ActionMethodSelectorAttribute attribute来逃避并覆盖IsValidForRequest方法。您可以在下面看到此方法只是确定特定参数(Name)是否与其中一个属性(Type)匹配。它应该与看起来像这样的视图模型绑定:

public class TestViewModel
{
    public string command { get; set; }
    public string moreProperties { get; set; }
}

该属性可能如下所示:

public class AcceptSubmitTypeAttribute : ActionMethodSelectorAttribute
{
    public string Name { get; set; }
    public string Type { get; set; }

    public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
    {
        return controllerContext.RequestContext.HttpContext
            .Request.Form[this.Name] == this.Type;
    }
}

然后,您可以使用AcceptSubmitType属性标记您的操作,如下所示:

[AcceptSubmitType(Name="command", Type="Transactions")]
public ActionResult Index(TestViewModel vm) 
{
    // use view model to do whatever
}

// to pseudo-override the "Index" action
[ActionName("Index")]
[AcceptSubmitType(Name="command", Type="All Transactions")]
public ActionResult Index_All(TestViewModel vm) 
{
    // use view model to do whatever
}

这也消除了单个控制器操作中逻辑的需要,因为它似乎真的需要两个不同的操作过程。

答案 1 :(得分:1)

纠正我如果我错了,但根据W3C标准,每张表格只有1个提交按钮。还有两个名字相同的控件是个坏主意。

答案 2 :(得分:0)

当你提交(在任何按钮上)你的整个页面被回发到控制器动作时,我遇到了同样的问题,但还没有找到一个像样的解决方案..也许你可以使用javascript'onclick'方法和为第一个按钮设置一个隐藏值为1,为第二个按钮设置一个隐藏值为0?

答案 3 :(得分:0)

这是一篇很好的博客,发现here

我喜欢添加AcceptParameterAttribute

的外观

答案 4 :(得分:0)

@CodeRush:W3C标准 允许每个表单提交多于1个。 http://www.w3.org/TR/html4/interact/forms.html。 “表单可能包含多个提交按钮”。