如何在ASP.NET MVC中实现插页式"加载..."页面?

int*_*bit 6 c# asp.net-mvc performance user-interface progressive-enhancement

我有一个SearchController,其动作可以执行一些长时间运行的搜索并返回结果页面.搜索可能需要1到60秒.搜索的URL是以下格式的HTTP GET请求:http://localhost/Search?my=query&is=fancy

我正在寻找的体验类似于那里的许多旅游网站.我想展示一个中间的"正在加载......"页面,理想情况是:

  1. 用户可以重新加载页面而无需重新启动搜索
  2. 后端搜索完成后,用户将重定向到结果
  3. 禁用JavaScript的浏览器的体验会降低
  4. 后退按钮/浏览器历史记录不应包含此插页式页面.
  5. 在短搜索(1秒)的情况下,它对获得结果或体验的时间没有显着影响(显着丑陋的页面闪烁,无论如何)

这些都是不错的选择.我对所有想法持开放态度!谢谢.

dav*_*dmx 5

为了保持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(...);
    }
}
Run Code Online (Sandbox Code Playgroud)

但就刷新而言,这给你带来了一些障碍.因此,您可以将它们重新合并为单个操作,该操作可以使用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(...);
    }
}
Run Code Online (Sandbox Code Playgroud)

这包括第2,3,4点,可以说是5.

要包含对#1的支持,意味着您将在session,db等中存储搜索结果.

在这种情况下,只需添加所需的缓存实现作为"在此处执行实际搜索"位的一部分,并添加check-for-cached-result以绕过加载页面.例如

if (TempData[SearchLoadingPageSentKey]==null)

if (TempData[SearchLeadingPageSentKey]==null && !SearchCache.ContainsKey(q))


Jan*_*m B 2

您可以按照以下方式进行操作:

  • 使用 AJAX 执行搜索请求(GET url)
  • 搜索url不返回结果,而是返回一些Json或XML内容以及实际结果的URL
  • 客户端页面在等待 AJAX 调用完成时显示“正在加载...”消息
  • 完成后客户端页面重定向到结果页面。

使用 jquery 的示例:

<div id="loading" style="display: none">
  Loading...
</div>
<a href="javascript:void(0);" 
  onclick="searchFor('something')">Search for something</a>

<script type="text/javascript">
  function searchFor(what) {
    $('#loading').fadeIn();
    $.ajax({ 
      type: 'GET', 
      url: 'search?query=' + what, 
      success: function(data) { 
        location.href = data.ResultsUrl; 
      } 
    });        
  }
</script>
Run Code Online (Sandbox Code Playgroud)

(编辑:)

控制器会是这样的:

public class SearchController 
{
  public ActionResult Query(string q) 
  {
    Session("searchresults") = performSearch();
    return Json(new { ResultsUrl = 'Results'});
  }

  public ActionResult Results()
  {
    return View(Session("searchresults"));
  }
}
Run Code Online (Sandbox Code Playgroud)

将其视为伪代码:我实际上没有测试它。