Multiple Submit Buttons in MVC3 - FormCollection has no Key/Value for Input Type Submit - Remote Validation Issue?
I have the two buttons in MVC3 application.
<input type="submit" name="command" value="Transactions" />
<input type="submit" name="command" value="All Transactions" />
When I click on a button, it posts back correctly but the FormCollection has no "command" keys. I also added a property "command" in the model and its value is null when the form is posted.
public ActionResult Index(FormCollection formCollection, SearchReportsModel searchReportsModel). {
if (searchReportsModel.command == "All Transactions")
...
else
....
}
I am using IE8. How can I use multiple buttons in MVC3? Is there a workaround for this issue? I did lot of research and could not find a solution.
Update:Dave: I tried your solution and it is throwing Http 404 error "The resource cannot be found".
Here is my code:
[HttpPost]
[AcceptSubmitType(Name = "Command", Type = "Transactions")]
public ActionResult Index(SearchReportsModel searchReportsModel)开发者_C百科
{
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;
}
}
The issue was resolved after commenting the following Remote validation attribute in the ViewModel (SearchReportsModel). It looks like it is a bug in MVC3:
//[Remote("CheckStudentNumber", "SearchReports", ErrorMessage = "No records exist for this Student Number")]
public int? StudentNumber { get; set; }
You might be able to get away with an ActionMethodSelectorAttribute
attribute and override the IsValidForRequest method. You can see below this method just determines whether a particular parameter (Name) matches one of it's properties (Type). It should bind with a view model that looks like this:
public class TestViewModel
{
public string command { get; set; }
public string moreProperties { get; set; }
}
The attribute could look like this:
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;
}
}
Then, you could tag your actions with the AcceptSubmitType
attribute like this:
[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
}
This also eliminates the need for logic in a single controller action since it seems you genuinely need two separate courses of action.
Correct me If I'm wrong, but according to W3C standard you should have only 1 submit button per form. Also having two controls with identical names is a bad idea.
when you submit (on any button) your whole page is posted back to the controller action, I have had the same problem but have not found a decent solution yet.. maybe you could work with a javascript 'onclick' method and set a hidden value to 1 for the first button and 0 for the second button or something like that?
This is a nice Blog about this found here
I like the look of adding in AcceptParameterAttribute
@CodeRush: The W3C standard does allow more than 1 submit per form. http://www.w3.org/TR/html4/interact/forms.html. "A form may contain more than one submit button".
精彩评论