3

如何防止用户在 MVC 中手动输入页面的 URL?

例如,我有一个返回错误视图的控​​制器方法:

    // GET: /Checkout/Error
    public ActionResult Error()
    {
        return View("Error")
    }

编辑:以及返回成功视图的控制器方法:

        // GET: /Checkout/Complete
    public ActionResult Complete()
    {
        var order = /* get the order */
        return View("Complete", order)
    }

如果订购过程中出现问题,我会重定向到它:

    public ActionResult Submit()
    {

        if (/*order succeeds*/) {
            return RedirectToAction("Complete");
        }
        else
            return RedirectToAction("Error");
    }

但是用户可以手动输入“www.mysite.com/Checkout/Error”,并在结帐工作流的上下文之外获取错误视图。

我环顾四周,发现 ChildActionOnly,但这似乎只适用于从视图中调用操作,这不适用于这里。

我想我可以在错误操作方法的开头手动检查订单是否确实存在问题,并在这种情况下返回错误视图并重定向用户,但似乎必须有一个更简单的防止用户手动导航到这样的页面的方法。

编辑:这同样适用于完成的视图。用户可以输入对应于操作的 URL。如何防止像这样调用此操作?

4

1 回答 1

3

您可以从控制器中删除 Error Action 方法,(但仍保留视图)并return View()使用RedirectToAction. 在这种情况下,您的 url 与 RedirectToAction 保持相同,它是一个302 响应,它告诉浏览器向Error操作方法发出新的 GET 请求。

public ActionResult Submit()
{
    if (/*order succeeds*/)
    {
        return RedirectToAction("Complete");
    }
    else
    {
        // TO DO : LOG ERROR
        return View("Error");
    }
}

~/Views/CurrentControllerName/假设您在or in 中有一个名为 Error 的视图~/Views/Shared

如果您的视图位于不同的目录中,您可以提供该目录的完整路径。

return View("~/Views/MyErrors/OrderError.cshtml");

如果需要,您可以将一些信息传递到错误视图。

编辑:根据评论。

如果您想将订单对象传递给完整视图,您可以使用TempData来传递您的订单对象。在 Completed 操作方法中,您可以检查您的特定 TempData 值是否可用,如果是,则显示正确的视图,否则告诉用户他们正在尝试访问不存在的页面/或任何其他相关消息/视图。

public ActionResult Submit()
{
    if (/*order succeeds*/)
    {
         // assuming newOrderId stores the Id of new order somehave.
        OrderVM orderVM=GetOrderFromSomeWhere(newOrderId);
        TempData["NewOrder"] =orderVM;
        return RedirectToAction("Complete");
    }
    else
    {
        // TO DO : LOG ERROR
        return View("Error");
    }
}

并在您的Complete操作方法中,检查您的 TempData 中是否有某些内容,然后向用户显示适当的视图。

public ActionResult Complete()
{      
  var model=TempData["NewOrder"] as OrderVM;
  if(model!=null)
  {
     return View(model);
  }
  return View("NotFound");
}

TempData在后台使用 Session 对象来存储数据。TempData 是一个非常短暂的实例,您应该只在当前和后续请求期间使用它!

Rachel 写了一篇很好的博客文章,解释了何时使用 TempData /ViewData。值得一读。

于 2014-03-04T21:38:33.030 回答