很多人在做MVC3的时候问过这样的问题:我在一个表单中有几个按钮,如何提交到不同的方法。
<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<input type="submit" value="Send" />
<input type="submit" value="Cancel" />
<% Html.EndForm(); %>
现在比较常用的方式是用多个表单:如
<% Html.BeginForm("Send", "MyController", FormMethod.Post); %>
<input type="submit" name="button" value="Send" />
<% Html.EndForm(); %>
<% Html.BeginForm("Cancel", "MyController", FormMethod.Post); %>
<input type="submit" name="button" value="Cancel" />
<% Html.EndForm(); %>
当然也可以给你的按钮一个名称,通过判断来解决这个问题
<% Html.BeginForm("MyAction", "MyController", FormMethod.Post); %>
<input type="submit" name="submitButton" value="Send" />
<input type="submit" name="submitButton" value="Cancel" />
<% Html.EndForm(); %>
对应控制器的方法
public class MyController : Controller {
public ActionResult MyAction(string submitButton) {
switch(submitButton) {
case "Send":
// delegate sending to another controller action
return(Send());
case "Cancel":
// call another action to perform the cancellation
return(Cancel());
default:
// If they've submitted the form without a submitButton,
// just return the view again.
return(View());
}
}
private ActionResult Cancel() {
// process the cancellation request here.
return(View("Cancelled"));
}
private ActionResult Send() {
// perform the actual send operation here.
return(View("SendConfirmed"));
}
}
不过,还有更好的方案。
<% using (Html.BeginForm()) { %>
<div>
<fieldset>
<legend>Account Information</legend>
<p>
<label for="username">Username:</label>
<%= Html.TextBox("username") %>
<%= Html.ValidationMessage("username") %>
</p>
<p>
<label for="email">Email:</label>
<%= Html.TextBox("email") %>
<%= Html.ValidationMessage("email") %>
</p>
<p>
<label for="password">Password:</label>
<%= Html.Password("password") %>
<%= Html.ValidationMessage("password") %>
</p>
<p>
<label for="confirmPassword">Confirm password:</label>
<%= Html.Password("confirmPassword") %>
<%= Html.ValidationMessage("confirmPassword") %>
</p>
</p>
</fieldset>
</div>
<% } %>
~/Controllers/AccountController.cs
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Register(string button, string userName, string email, string password, string confirmPassword)
{
if (button == "cancel")
return RedirectToAction("Index", "Home");
ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
if (ValidateRegistration(userName, email, password, confirmPassword))
{ // Attempt to register the user
MembershipCreateStatus createStatus = MembershipService.CreateUser(userName, password, email);
if (createStatus == MembershipCreateStatus.Success)
{
FormsAuth.SignIn(userName, false /* createPersistentCookie */);
return RedirectToAction("Index", "Home");
}
else
{
ModelState.AddModelError("_FORM", ErrorCodeToString(createStatus));
}
}
// If we got this far, something failed, redisplay form
return View();
}
public class AcceptParameterAttribute : ActionMethodSelectorAttribute
{
public string Name { get; set; }
public string Value { get; set; }
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo)
{
var req = controllerContext.RequestContext.HttpContext.Request;
return req.Form[this.Name] == this.Value;
}
}
[ActionName("Register")]
[AcceptVerbs(HttpVerbs.Post)]
[AcceptParameter(Name="button", Value="cancel")]
public ActionResult Register_Cancel()
{
return RedirectToAction("Index", "Home");
}
[AcceptVerbs(HttpVerbs.Post)]
[AcceptParameter(Name="button", Value="register")]
public ActionResult Register(string userName, string email, string password, string confirmPassword)
{
// process registration
}
<% using (Html.BeginForm()) { %>
<div>
<fieldset>
<legend>Account Information</legend>
<p>
<label for="username">Username:</label>
<%= Html.TextBox("username") %>
<%= Html.ValidationMessage("username") %>
</p>
<p>
<label for="email">Email:</label>
<%= Html.TextBox("email") %>
<%= Html.ValidationMessage("email") %>
</p>
<p>
<label for="password">Password:</label>
<%= Html.Password("password") %>
<%= Html.ValidationMessage("password") %>
</p>
<p>
<label for="confirmPassword">Confirm password:</label>
<%= Html.Password("confirmPassword") %>
<%= Html.ValidationMessage("confirmPassword") %>
</p>
<p>
<button name="button">Register</button>
</p>
</fieldset>
</div>
<% } %>
呵呵 。很有意思的解决方案。。。 真是有才。 不过还有个非常棒的方案 ~~~
<button name="button" type="button" οnclick="$('#cancelForm').submit()">Cancel</button>
using (Html.BeginForm("Register_Cancel", "Account", FormMethod.Post, new { id="cancelForm" })) {}
好吧,暂时把它称为最终解决方案。^_^
public class HttpParamActionAttribute : ActionNameSelectorAttribute {
public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo) {
if (actionName.Equals(methodInfo.Name, StringComparison.InvariantCultureIgnoreCase))
return true;
if (!actionName.Equals("Action", StringComparison.InvariantCultureIgnoreCase))
return false;
var request = controllerContext.RequestContext.HttpContext.Request;
return request[methodInfo.Name] != null;
}
}
<% using (Html.BeginForm("Action", "Post")) { %>
<!— …form fields… -->
<input type="submit" name="saveDraft" value="Save Draft" />
<input type="submit" name="publish" value="Publish" />
<% } %>
public class PostController : Controller {
[HttpParamAction]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveDraft(…) {
//…
}
[HttpParamAction]
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Publish(…) {
//…
}
}
ok ,这个解决方案非常的nice,很性感。喜欢的朋友可以使用~~~
最后提供下最终解决方案的Demo:MVC一个表单中多个按钮的解决方案