【问题标题】:MVC3: PRG Pattern with Search Filters on Action MethodMVC3:在动作方法上带有搜索过滤器的 PRG 模式
【发布时间】:2012-05-17 00:28:24
【问题描述】:

我有一个带有 Index 方法的控制器,它有几个可选参数用于过滤返回到视图的结果。

public ActionResult Index(string searchString, string location, string status) {
    ...

product = repository.GetProducts(string searchString, string location, string status);

return View(product);
}

我想实现如下所示的 PRG 模式,但我不知道该怎么做。

[HttpPost]
public ActionResult Index(ViewModel model) {
    ...
    if (ModelState.IsValid) {
        product = repository.GetProducts(model);
    return RedirectToAction(); // Not sure how to handle the redirect
    }
return View(model);
}

我的理解是,如果出现以下情况,则不应使用此模式:

  • 除非您实际存储了一些数据(我没有),否则您不需要使用此模式
  • 您不会使用此模式来避免刷新页面时来自 IE 的“您确定要重新提交”消息(有罪)

我应该尝试使用这种模式吗?如果是这样,我将如何处理?

谢谢!

【问题讨论】:

  • 我肯定会使用这种模式来避免 IE 对话框“你不会使用这种模式来避免刷新页面时来自 IE 的“你确定要重新提交”消息(有罪)”它通常不鼓励最终用户,他们通常不知道该怎么做“我点击取消吗?我点击确定了吗?啊!太多的决定!”

标签: asp.net-mvc-3


【解决方案1】:

PRG 代表 Post-Redirect-Get。这意味着当您将一些数据发回服务器时,您应该重定向到GET 操作。

为什么我们需要这样做?

假设您有一个表单,您可以在其中输入客户注册信息并单击提交,然后将其发布到 HttpPost 操作方法。您正在从表单中读取数据并将其保存到数据库中,并且您没有进行重定向。相反,您将停留在同一页面上。现在,如果您刷新浏览器(只需按 F5 按钮),浏览器将再次执行类似的表单发布,您的 HttpPost Action 方法将再次执行相同的操作。 IE;它将再次保存相同的表单数据。这是个问题。为了避免这个问题,我们使用 PRG 模式。

PRG 中,您单击提交,HttpPost 操作方法将保存您的数据(或它必须做的任何事情),然后重定向到 Get 请求。所以浏览器会向那个 Action 发送一个Get 请求

RedirectToAction 方法向浏览器返回一个HTTP 302 响应,这会导致浏览器向指定的操作发出 GET 请求。

[HttpPost]
public ActionResult SaveCustemer(string name,string age)
{
   //Save the customer here
  return RedirectToAction("CustomerList");

}

以上代码将保存数据并重定向到客户列表操作方法。所以你的浏览器网址现在将是http://yourdomain/yourcontroller/CustomerList。现在,如果您刷新浏览器。 IT 不会保存重复的数据。它只会加载 CustomerList 页面。

在您的搜索操作方法中,您不需要重定向到获取操作。您可以在 products 变量中找到搜索结果。只需将其传递给所需的视图即可显示结果。您不必担心重复的表单发布。所以你很擅长。

[HttpPost]
public ActionResult Index(ViewModel model) {

    if (ModelState.IsValid) {
        var products = repository.GetProducts(model);
        return View(products)
    }
  return View(model);
}

【讨论】:

  • 感谢您的解释和示例。我假设如果我没有验证任何内容,那么我可以省略 ModelState 检查,对吗?
  • @Rich。是的。如果您没有验证任何内容,您可以删除它(使用最后一个 return View(model) 语句)。
【解决方案2】:

重定向只是一个 ActionResult ,它是另一个动作。因此,如果您有一个名为 SearchResults 的操作,您只需说

return RedirectToAction("SearchResults");

如果动作在另一个控制器中...

return RedirectToAction("SearchResults", "ControllerName");

带参数...

return RedirectToAction("SearchResults", "ControllerName", new { parameterName = model.PropertyName });

更新

我想到您可能还希望选择将复杂对象发送到下一个操作,在这种情况下您的选择有限,TempData 是首选方法

使用你的方法

[HttpPost]
public ActionResult Index(ViewModel model) {
    ...
    if (ModelState.IsValid) {
        product = repository.GetProducts(model);
        TempData["Product"] = product;
        return RedirectToAction("NextAction");
    }
    return View(model);
}

public ActionResult NextAction() {
    var model = new Product();
    if(TempData["Product"] != null)
       model = (Product)TempData["Product"];
    Return View(model);
}

【讨论】:

  • 没有问题,我赞成@shyju,因为他同样正确:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-20
  • 2014-11-25
  • 2015-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多