Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc ASP.NET MVC中的Post重定向Get和Restful URL验证_Asp.net Mvc_Post Redirect Get - Fatal编程技术网

Asp.net mvc ASP.NET MVC中的Post重定向Get和Restful URL验证

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)模

我有一个用于编辑页面的restful URL。这在控制器上作为一个编辑方法实现,该方法接受GET请求,并作为一个编辑方法接受POST请求

这意味着您可以访问编辑URL,它将为GET显示表单或为POST保存表单

[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)获取该数据