我想知道在asp.net mvc 3 RC中提交表单时如何实现多个表单操作。
如果我正在编辑用户,例如我想要一个带有以下按钮的操作栏;
“保存”| “保存并关闭”| “取消”
保存 - 提交表单并保存,返回编辑屏幕。可以轻松实现为标准输入/提交按钮。这里没什么特别的。
此控制器代码可能类似于
public ActionResult Edit(UserViewModel model)
{
...
return RedirectToAction("Edit", model.Id");
}
取消 - 只需返回上一屏幕即可。我正在考虑为此使用锚标记。
<a href="@Request.UrlReferrer" class="button">Cancel</a>
但是当您需要提交相同的表单数据时,我对如何实施“保存并关闭”感到困惑。我想知道有一个可以为空的关闭参数吗?
public ActionResult Edit(UserViewModel model, bool? close)
{
...
return close.GetValueOrDefault(false) ? RedirectToAction("Index", model.Id" : RedirectToAction("Edit", model.Id");
}
但是在这种情况下如何提交这个额外的参数以及表格?
如果可能的话,我希望有一个表单操作来处理提交,就像上面的模型一样。
如果有其他人想出了一个关于这个想法的好的用户交互模型,我也很感兴趣。
解决方案
我最终在下面使用了Omar的建议,但我没有传入一个字符串,而是接受了枚举,所以我不必在所有控制器中进行字符串检查。
public ActionResult Edit(UserViewModel model, FormAction actionType)
{
// pre-check
if (actionType == FormAction.Cancel)
// just return user to previous view and don't save.
// Save code
if (actionType == FormAction.Save)
return ...
else if (actionType == FormAction.SaveAndClose)
....
}
因为我想在<input>
按钮上使用更友好的“保存并关闭”文本,但想要使用枚举,我实现了一个用于进行解析的FormAction的自定义ModelBinder。
我没有使用<button>
代码,因为<input>
代码的主题已经存在。
答案 0 :(得分:19)
您可以在表单中包含多个提交按钮,这些按钮具有相同的name
属性但属性不同value
。单击哪个按钮,关联的value
将发布到服务器。
您可以使用Cancel
的简单链接,但无论如何我都会将其作为按钮添加。
<input type="submit" name="actionType" value="Save" />
<input type="submit" name="actionType" value="Save and Close" />
<input type="submit" name="actionType" value="Cancel" />
在你的行动中,测试价值。
public ActionResult Edit(string actionType)
{
if(actionType == "Save")
{
// Save action
}
else if (actionType == "Save and Close")
{
// Save and quit action
}
else
{
// Cancel action
}
}
如果您不喜欢在value
属性中添加长文本,则可以使用标准HTML <button>
标记,该标记可让您定义单独的值和单独的文本。
答案 1 :(得分:5)
@Omar的建议很棒。以下是我在提示用户删除对象时需要确认的情况下,使其更加通用。 注意!在HttpPost我再次拉动对象而不是使用传递给方法的项目。您可以通过让视图包含所有属性来减少数据库调用,以便填充“项目”。
这是视图模型
public class DeleteViewModel<T> {
public string ActionType { get; set; }
public T Item { get; set; }
}
<强>控制器强>
public ActionResult Delete(int id) {
DeleteViewModel<Category> model = new DeleteViewModel<Category>() {
Item = categoryRepository.Categories.FirstOrDefault(x => x.CategoryID == id)
};
return View(model);
}
[HttpPost]
public ActionResult Delete(DeleteViewModel<Category> model) {
if (model.ActionType == "Cancel")
return RedirectToAction("Index");
else if (model.ActionType == "Delete") {
var cat = categoryRepository.Categories.FirstOrDefault(x => x.CategoryID == model.Item.CategoryID);
categoryRepository.Delete(cat);
return RedirectToAction("Index");
}
//Unknown Action
return RedirectToAction("Index");
}
查看强>
<div class="actions">
<div class="actions-left"><input type="submit" value="Cancel" name="ActionType"/></div>
<div class="actions-right"><input type="submit" value="Delete" name="ActionType" /></div>
</div>