如何最好地实施保存|保存并关闭|取消ASP.NET MVC 3 RC中的表单操作

时间:2010-11-24 06:22:48

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

我想知道在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>代码的主题已经存在。

2 个答案:

答案 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>