Asp.net mvc ASP.NET MVC中的Post重定向Get和Restful URL验证
我有一个用于编辑页面的restful URL。这在控制器上作为一个编辑方法实现,该方法接受GET请求,并作为一个编辑方法接受POST请求 这意味着您可以访问编辑URL,它将为GET显示表单或为POST保存表单Asp.net mvc ASP.NET MVC中的Post重定向Get和Restful URL验证,asp.net-mvc,post-redirect-get,Asp.net Mvc,Post Redirect Get,我有一个用于编辑页面的restful URL。这在控制器上作为一个编辑方法实现,该方法接受GET请求,并作为一个编辑方法接受POST请求 这意味着您可以访问编辑URL,它将为GET显示表单或为POST保存表单 [HttpGet] public ActionResult Edit(int id) { ... } [HttpPost] public ActionResult Edit(EditModel model) { ... } Post Redirect Get(PRG)模
[HttpGet]
public ActionResult Edit(int id) {
...
}
[HttpPost]
public ActionResult Edit(EditModel model) {
...
}
Post Redirect Get(PRG)模式看起来是黑白相间的,因为它本质上将每个Post重定向回Get操作。然而,我需要确信这是正确的做法
我的计划是,在POST操作中,如果模型有效,我将使用POST重定向Get模式将用户发送到一个合理的位置(可能是索引或详细信息操作)
但是,如果存在模型验证问题,我仍然希望只显示视图。我不想重定向用户,因为这意味着将模型和ModelState填充到临时数据中并重定向到GET操作,然后在GET操作中添加逻辑来处理临时数据。我可以通过简单地显示视图来避免所有这些
是的,如果用户按F5,它将重新提交表单,并向他们显示“重新提交警告”,但随后显示同一页面(要求他们修复验证错误)。但是,它们似乎不太可能达到F5,而且也没有双重提交的危险,因为表单将再次无法通过验证
如果验证通过,用户将被重定向,他们将不会重复提交
因此,我应该实现额外的代码并将数据填充到临时数据中,以便严格遵循PRG模式,还是在表单有效且存储数据时使用PRG模式更明智?您应该只在表单信息有效时执行重定向;如果提交错误,请使用相同的编辑方法返回视图 这样做符合PRG,因为如果模型无效,则不允许对服务器上对象的状态进行任何更改。PRG主要用于防止多个POST以不可预知的方式更改服务器对象(例如,业务对象、数据库表等)的状态;但是,在您的验证示例中,用户可以根据需要多次点击“重新提交”,并且它们将始终返回到带有验证错误的初始视图——服务器上没有任何更改。因此,您的做法是正确的:仅当您的模型通过了表示层中的验证时才发出重定向。即使它突出显示了一个重要事实-PRG并不一定意味着“发布时盲目返回重定向”-有时您仍可能希望执行重定向并保留modelstate
处理该场景的最简单方法是使用操作过滤器将modelstate导出到会话(在重定向之前),然后导入modelstate(在执行新操作之前)。有两篇关于ASP.NET MVC最佳实践的优秀博文()。它们已经很老了,但其中的许多技巧仍然非常适用。中的第13条提示正是您想要的。PRG是正确的选择 您对操作执行POST,如果modelstate无效,您只需将modelstate数据“导出”到变量中并重定向到get操作 与公认的答案相反,这有一个好处,即您不需要重写[Post]操作上的代码来重新创建视图 在get操作中,加载从post-one导出的ModelState TempData是做这些事情的绝佳场所,代码如下:
[HttpGet]
public ActionResult Edit(int id) {
// import model state from tempdata
...
}
[HttpPost]
public ActionResult Edit(EditModel model) {
// if modelstate is invalid
// save modelstate in tempdata
// redirect to Edit/{id}
// else
...
RedirectToAction("List")
}
这可以使用AttributeFilter实现自动化,这里有一篇由@ben foster创建的优秀帖子:
我使用了Kazi Manzur的改进版解决方案来解决验证失败的问题,现在我绝对喜欢“严格PRG”。我知道这需要更多的努力,但strict PRG确实为用户提供了非常好的体验。我从任何知名的来源都找不到任何支持Kazi Manzur的“解决方案”建议的方法的东西。他说,在三篇链接的博文中,有一篇主张这种方法,一篇不再加载,另外两篇实际上主张香草PRG,即只在成功时重定向,在失败时返回视图。这是一种非常糟糕的方法,因为它需要状态,而一个好的HTTP应用程序,也就是说一个RESTful应用程序不应该需要状态。@ChrisPratt:我不知道你指的是哪些帖子没有加载-提示13下的所有(四)链接都为我加载。博客帖子(以及答案和问题…)已经很老了,所以被认为是“最佳实践”的东西可能已经改变了——今天,这很可能不是处理无效帖子后显示表单的最佳方式。我仍然认为这构成了有价值的知识,尽管-使用
ActionFilter
这种方式是一种锤子,但并非所有东西都是匹配的钉子。和所有事情一样,在适当的时候明智地使用它,而不是盲目地、总是这样。@Endri:post是从2011年开始的;如果当前版本的框架中的最佳实践没有太大的不同,我会非常惊讶。是的,我同意。。。但这就是我从阅读中得到的,当我不知道如何编辑断开的链接时,该如何处理它们。然而,这仍然是一个有价值的答案。。。可能最好是编辑以删除文章引用。我认为您在这里创建了一个稻草人论点:与公认的答案相比,这有一个好处,即您不需要在[Post]操作中重写代码来重新创建视图。
您不需要根据公认的答案重写任何代码,您只需重新显示视图:返回视图(模型)
如果视图需要访问数据库获取一些值或进行填充以创建viewmodel,则应使用两种方法(get和PO)获取该数据