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

Jos*_*yes 13 asp.net-mvc asp.net-mvc-3

我想知道在asp.net mvc 3 RC中提交表单时如何实现多个表单操作.

如果我正在编辑用户,例如我想要一个带有以下按钮的操作栏;

"保存"| "保存并关闭"| "取消"

保存 - 提交表单并保存,返回编辑屏幕.可以轻松实现为标准输入/提交按钮.这里没什么特别的.

这可能是控制器代码

public ActionResult Edit(UserViewModel model)
{
  ...
  return RedirectToAction("Edit", model.Id");
}
Run Code Online (Sandbox Code Playgroud)

取消 - 只需返回上一屏幕即可.我正在考虑为此使用锚标签.

<a href="@Request.UrlReferrer" class="button">Cancel</a>
Run Code Online (Sandbox Code Playgroud)

但是当你需要提交相同的表单数据时,我很难理解如何实现"保存并关闭".我想知道有一个可以为空的关闭参数吗?

public ActionResult Edit(UserViewModel model, bool? close)
{
  ...
  return  close.GetValueOrDefault(false) ? RedirectToAction("Index", model.Id" : RedirectToAction("Edit", model.Id");
}
Run Code Online (Sandbox Code Playgroud)

但是,在这种情况下,如何将此额外参数与表单一起提交?

如果可能的话,我想在上面的模型中使用单个表单操作来处理提交.

我也很感兴趣,如果有其他人提出了一个很好的用户交互模型围绕这个想法.

我最终使用了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)
     ....
}
Run Code Online (Sandbox Code Playgroud)

因为我想在<input>按钮上使用更友好的"保存并关闭"文本但想要使用枚举,我实现了一个用于FormAction的自定义ModelBinder来进行解析.

我没有使用<button>标签,因为标签的主题已经存在<input>.

Oma*_*mar 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" />
Run Code Online (Sandbox Code Playgroud)

在您的行动中,测试值.

public ActionResult Edit(string actionType)
{
    if(actionType == "Save")
    {
        // Save action
    }
    else if (actionType == "Save and Close")
    {
        // Save and quit action
    }
    else
    {
        // Cancel action
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您不喜欢在value属性中包含长文本,则可以使用标准HTML <button>标记,该标记允许您定义单独的值和单独的文本.


anA*_*ent 5

@Omar的建议很棒.以下是我在提示用户删除对象时需要确认的情况下,使其更加通用.注意!在HttpPost我再次拉动对象而不是使用传递给方法的项目.您可以通过使视图包含所有属性来减少数据库调用,以便填充"项目".

这是视图模型

public class DeleteViewModel<T> {
    public string ActionType { get; set; }
    public T Item { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

调节器

    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");
    }
Run Code Online (Sandbox Code Playgroud)

视图

    <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>   
Run Code Online (Sandbox Code Playgroud)