代码之家  ›  专栏  ›  技术社区  ›  Frank Krueger

在ASP.NET MVC中,还有什么方法可以发布重定向get?

  •  1
  • Frank Krueger  · 技术社区  · 15 年前

    通过POST提交表单,然后重定向到相同或不同的URL的ASP.NET MVC模式非常容易编码。

    想象一下这个场景:

    1. 用户前往 /产品/42/编辑 查看和编辑产品42。
    2. 他们在那个页面上看到一些疯狂的东西,编辑它,然后点击保存。这使得一个帖子 /产品/42/编辑
    3. 该操作将更新数据并重定向到 返回的视图 /产品/42/编辑
    4. 用户看到更新后的数据,很高兴。
    5. 一小时后,他们点击刷新,看看是否有人弄乱了产品42。
    6. 因为上次检索 /产品/42/编辑 是一篇文章,他们的浏览器要求重新提交表单数据。这很烦人 危险,因为它会覆盖其他人的数据。

    我担心即使我使用两个不同的URL来发布和获取 /产品/42/编辑 /产品/ 42 ,表示浏览器仍将请求重新发布并可以销毁数据。我错了吗?

    可以使用哪些替代方法,以便在提交产品更改后,用户可以安全地单击刷新以获取更新的视图?

    更新 我明白了,我的问题和设计都搞混了,对此我深表歉意。我发现在帖子和GeT之间共享URL(操作)是个坏主意。如果这两个不同,那么我就不会有“刷新导致重新发布”的问题了,这是正确的假设吗?

    6 回复  |  直到 15 年前
        1
  •  5
  •   Femaref    15 年前

    更新:是的。

    使用/product/id/进行查看,使用/product/id/编辑进行编辑,编辑后将其重定向到/product/id/。

    问题解决了。想知道您为什么使用/product/id/edit进行查看和编辑。

        2
  •  8
  •   reach4thelasers    15 年前

    虽然我同意前面的回答中所说的,即在发布完成后不再将用户返回到编辑视图;但这并不能回答为什么按刷新重新发布表单的问题。

    这里是解决“在浏览器中刷新导致另一篇文章”问题的解决方案。

    目前,您正在进行以下操作:

    [AcceptVerbs(HttpVerbs.Post)]    // <--  this action will be used for POSTs
    EditProduct(string data1, string data2) 
    {
        // Handle Data, save to DB
        // Do some work
        return View("EditProduct");  //  <-- You are rendering the view from
    }                                //      A post action - this is bad!  
    

    当你真的应该这样做的时候:


    [AcceptVerbs(HttpVerbs.Post)]    //  <-- This action will be used for POSTs
    EditProduct(string data1, string data2) 
    {
        // Handle Data, save to DB
        // Do some work
        return RedirectToAction("EditProduct"); // <-- Redirect to a GET Action
    }
    
    [AcceptVerbs(HttpVerbs.Get)]   //  <-- This action will be used for GETs
    EditProduct() 
    {
    
        return View("EditProduct"); // <-- Render the view from the GET action
    }                               //     So when you refresh it will refresh the GET
    

    关键是,不要返回视图以响应日志,否则浏览器中的最后一个请求是日志请求,在浏览器中按刷新将重新发布。相反,当完成post操作后,使用redirectToAction()重定向到“get”操作。get操作反过来返回视图。这意味着浏览器中的前一个请求是一个GET请求,如果您按下“刷新”,它将再次收到该请求,而不会重新发送该请求。我在开始使用MVC时也犯了同样的错误。

        3
  •  1
  •   Dmytrii Nagirniak    15 年前

    如果你 真的? 希望有相同的页面用于查看和编辑,并且需要处理 并发性 您可以包括保留上次更新日期的隐藏字段。所以流量是:

    1. 用户1提交数据。
    2. 呈现相同的页面,但使用日期元素(比如date1)。
    3. 用户2提交此页面。
    4. 用户1再次提交。该操作比较日期1和实际更新日期。
    5. 在实际情况下,它们是不同的,因此操作不应该更新并告诉用户有关它的信息。

    这只是另一个选择。

        5
  •  0
  •   Darin Dimitrov    15 年前

    你是说当用户点击刷新时,你会得到一个过时的视图。因此,我假设您的get操作正在使用post操作中存储在tempdata中的某个对象。在这种情况下,可能的解决方法是使用会话而不是tempdata来存储post操作的结果。

        6
  •  0
  •   Robert Harvey    15 年前

    为了使您的发布表单以您描述的方式工作,它需要从数据库中读取数据并预填充表单上的字段。它需要从您第一次输入相关的URL开始执行此操作。

    然后,在发布时,需要在验证后将值保存到数据库中。这将完成您的往返循环。

    如果页面是空白的“新记录”页面,那么您是对的,它只会在验证失败时往返一次。在F5上,按设计,它只会给你一个新的空白表单。

    推荐文章