6

私はSearchControllerに長時間実行される検索を実行して結果ページを返すアクションを持っています。検索には1〜60秒かかることがあります。検索のURLは、次の形式のHTTP GETリクエストです。http://localhost/Search?my=query&is=fancyASP.NET MVCでインタースティシャルの「読み込み中...」ページを実装するにはどうすればよいですか?

私が探している経験は、そこにある多くの旅行サイトに似ています。私は、理想的には、どこの中間「ロード...」ページを表示したいと思います:

  1. ユーザーは、バックエンドの検索が終了したら、検索
  2. を再起動せずにユーザーがページをリロードすることができます結果にリダイレクトされます
  3. JavaScriptを無効にしたブラウザでは、エクスペリエンスが低下します
  4. 戻るボタン/ブラウザの履歴にこのインタースティシャルページが含まれてはいけません。
  5. 短い検索(1秒)の場合、それが結果に到達するための時間や経験のいずれかに重大な影響はありません(非常に醜いページが点滅し、何でも)

ものいいですね。私はすべてのアイデアを公開しています!ありがとう。

答えて

2

あなたはそれを次のように行うことができます:

  • を検索URLが結果を返さないAJAX
  • で検索リクエスト(GETの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> 

(編集:)

コントローラのようなものになります:

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

    public ActionResult Results() 
    { 
    return View(Session("searchresults")); 
    } 
} 

が、それは擬似コードを考えてみましょう:私は実際にはしませんでした試して。

5

javascriptを使用しないようにするには、検索を複数のアクションに分割できます。

最初のアクション(/ Search /?q = whodunit)は、(フォームを再表示する必要があるかどうかを知るために)パラメータの検証を行ってからメタリフレッシュを使用してブラウザは「本当の」検索動作に戻ります。

次の2つの別々のコントローラのアクションでこれを実装することができます(たとえば検索と結果):

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を使用して2フェーズプロセスの信号を送ることができる単一のアクションに再統合することができます。

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(...); 
    } 
} 

これは、#1のサポートを含めるにはポイント2、3、4、間違いなく5

をカバーでは、検索のいずれかのセッションでは、DBなどの結果を格納しようとしていることを意味し

この場合、「ここで実際に検索します」ビットの一部として必要なキャッシュ実装を追加し、読み込みページをバイパスするためにキャッシュのチェックを追加します。例えば

if (TempData[SearchLoadingPageSentKey]==null)

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

2

良い質問になります。私は間もなくasp.net mvcで同様のソリューションを実装しなければならないかもしれませんが、Webフォームベースのソリューションとは根本的に異なる実装を必要とするとは思われません。

私は、以前にWebフォームと上記の最初のリンクに基づいて実装を構築しました。基本的なプロセスは次のとおりです。

  1. 初期ページが検索が
  2. パラメータ/ wをこのページには、このページには、「処理中」のページにユーザーをリダイレクトし、長時間実行タスク
  3. を実行する新しいスレッドを起動し、要求されますこれはhttpリフレッシュヘッダーが2秒ごとにリロードするように設定されています
  4. 検索を実行するスレッドは、%完了を示す「グローバル」静的検索進行オブジェクトを更新し、処理中ページが進行状況を表示します。 (各検索はHashtableのGUID idによって格納されるため、複数の同時検索がサポートされます)
  5. スレッドが完了すると、検索処理がそのまま更新され、処理中ページでこれが検出されると、 "ページ。

(確かにMSDNから2番目のリンクをチェックし、それは私が唯一のオーバースキムきた1全く異なる解決策だが、ではない。)

これの利点は、それがすべてでJavascriptを必要としないことです。私が考えることができる最大の欠点は、(ユーザーの視点から)完全に「Web 2.0」ではないことと、ユーザーは一連のブラウザの更新を待たなければならないことです。

@Jan Willem BのAJAXベースの提案は、このマルチスレッド待ち状態パターンの実行可能な代替方法でなければなりません。あなたの要件を最もよく満たすものは、自分で決めなければならないものです。私が投稿したaspfree.comの例は、あなたの要件の大部分を満たしていなければならず、WebフォームとしてMVCでも同様に動作します。

関連する問題