为了保持 javascript-less,您可以将搜索分解为多个操作。
第一个操作 (/Search/?q=whodunit) 只是对您的参数进行一些验证(这样您就知道是否需要重新显示表单),然后返回一个使用元刷新将浏览器指向的视图“真正的”搜索动作。
您可以使用两个单独的控制器操作(例如搜索和结果)来实现这一点:
public ActionResult Search(string q)
{
if (Validate(q))
{
string resultsUrl = Url.Action("Results", new { q = q });
return View("ResultsLoading", new ResultsLoadingModel(resultsUrl));
}
else
{
return ShowSearchForm(...);
}
}
bool Validate(string q)
{
// Validate
}
public ActionResult Results(string q)
{
if (Validate(q))
{
// Do Search and return View
}
else
{
return ShowSearchForm(...);
}
}
但这给你带来了一些令人耳目一新的障碍。因此,您可以将它们重新合并为一个动作,该动作可以使用 TempData 向自己发出两阶段过程的信号。
static string SearchLoadingPageSentKey = "Look at me, I'm a magic string!";
public ActionResult Search(string q)
{
if (Validate(q))
{
if (TempData[SearchLoadingPageSentKey]==null)
{
TempData[SearchLoadingPageSentKey] = true;
string resultsUrl = Url.Action("Search", new { q = q });
return View("ResultsLoading", new ResultsLoadingModel(resultsUrl));
}
else
{
// Do actual search here
return View("SearchResults", model);
}
}
else
{
return ShowSearchForm(...);
}
}
这涵盖了第 2、3、4 点和可以说是第 5 点。
包括对#1 的支持意味着您将在会话、数据库等中存储搜索结果。
在这种情况下,只需将所需的缓存实现添加为“在此处进行实际搜索”位的一部分,并添加一个检查缓存结果以绕过加载页面。例如
if (TempData[SearchLoadingPageSentKey]==null)
变成
if (TempData[SearchLeadingPageSentKey]==null && !SearchCache.ContainsKey(q))