0

コントローラーを持っていることを想像してください

1) 長い操作を開始し、セッションに何かを書き込み、すぐにユーザーフレンドリーなメッセージをレンダリングするアクション:

    public ActionResult Search(string query)
    {
        _searchProvider.Ready += SearchResultReady;
        _searchProvider.Request(query);
        Session["query"] = query;
        return Results();
    }
    private void SearchResultReady(IEnumerable<IObject> results)
    {
        Session["searchResult"] = results.ToList();
    }

「検索」が完了すると、結果が保存されSessionます。

これを行う理由は、準備ができたときに結果を表示するためです ( でリクエストする必要がありますajax) 。

public ViewResult Results()
{
    if (Session["searchResult"] == null)
        return View("Wait");

    var query = Session["query"] as string;
    var list = Session["searchResult"] as IList<IObject>;
    var model = new ResultModel(query, list);
    return View("Results", model);
}

ここでの問題は、Ready イベントで、Sessionが nullであることです。

リクエスト間でコントローラーの状態を保存する適切な方法は何ですか?

4

1 に答える 1

1

これにはセッションを使用できません。セッションは AJAX 経由で送信されないため、ヒットしている API エンドポイントは、ルックアップするセッション トークンを取得しません。実際、真の REST API を扱っている場合、そもそもセッションのようなものはありません。HTTP はステートレス プロトコルです。

さらに、コントローラー アクション内で何らかの作業を行った場合、結果が実際に準備されるまで応答は返されないため、後で AJAX を使用して取得する必要がなくなります。非同期を実装したとしても (ここでは実行していません)、スレッドを解放してサーバー プールに戻して、アクションが完了するまで他の要求に対応できるようにするだけです。応答が速く返ることはありません。

最初にページをロードしてから、長時間実行されるタスクからデータをフェッチする場合は、単純にページをレンダリングし、ページが AJAX を介して要求を開始したら、API エンドポイントに作業を行わせる必要があります。スレッドをデッドロックしないように async を実装し、AJAX リクエストが完了するのを待っている間、ロード アニメーションをユーザーに表示します。

アップデート

コントローラ アクション

public ActionResult Search(string query)
{
    return View();
    // that's right: do nothing here, just return the view
}

ビューの JavaScript

var interval;

$(document).ready(function () {
    var query = location.search.split('=')[1];
    $.post('/do/some/work', { query: query }, function (data) {
        // render data
        clearInterval(interval);
    });

    function checkStatus() {
        $.get('/check/on/status', function (data) {
            // data would contain percentage value or something,
            //use that to update progress bar
        });
    }

    interval = setInterval(checkStatus, 1000);
});

それはすべて迅速で汚いです。検索クエリを取得するためのより堅牢な方法を見つける必要があります。アクションでビューモデルを使用して設定し、それをビューなどに返すこともできます。intervalまた、JavaScript は適切な名前空間を使用する必要があるため、他のスクリプトが変数などを介して実行されることはありません。

于 2013-10-22T16:17:33.007 に答える