2

ASP.NET MVC フレームワークとその配管に不慣れだったので、ここにたどり着きました。誰かが私の質問を読んで検討するのにかかる忍耐に感謝します!

さて、シナリオは次のとおりです。検索に基づいたデータ、他のデータからのドリルダウン、コンテキスト固有のデータに基づくレポートを表示するグリッドを備えた多数のページを持つアプリケーションがあります (つまり、それらは Foo の詳細ページにあり、次に をクリックします)。 Foo に関連するデータの表を示すリンク) など。

アプリ全体にあるこれらのページのすべてから、ユーザーは名前と説明を付けて「レポート」またはグリッドを保存できます。これは、グリッドに表示されるデータを実際に保存するのではなく、グリッドがどのように見えるかを定義するパラメーターを保存し、データを取得するために使用されたパラメーターを保存し、「場所」を定義するパラメーターを保存します。アプリ (アクション、コントローラー、ルート) - 基本的に、レポート/グリッドとその構築方法に関する一連のメタデータです。

これらの保存されたレポートはすべて、アプリの特定のページに名前と説明を表示する単一のリストで利用でき、それぞれが「/Reports/Saved/248」のような一般的な URL にリンクしています (248 は例です)。レポートの ID)。

ここに私が助けが必要な部分があります:

URL「/Reports/Saved/248」を介してアクションに到達し、その特定のレポートのデータベースからメタデータを取得する場合、そのデータとリクエストを同じアクション、コントローラー、および表示に使用されるルートにリダイレクトするにはどうすればよいですかレポートが最初に保存されたビュー 基本的に、保存元と同じ URL を使用して、ユーザーが同じビューでレポートを表示できるようにしたいと考えています。可能であれば、メソッド呼び出しを行っているかのように、基本的に同じアクションを「呼び出す」ことができるとよいでしょう。


更新: 残念ながら、レポート ページ (つまり、これらのグリッドが表示されるページ) は RESTful URL を使用していません。たとえば、高度な検索ページと呼ばれるものがあります。選択リスト、テキストボックスなどを含むフォームから。ユーザーがそのページを送信すると、モデルバインダーが構築する複雑なタイプを受け入れるアクションに対して POST を実行します。ユーザーがデータベースから保存済みの高度な検索を選択します。その例は私の問題を象徴しています。

ありがとう

4

2 に答える 2

2

RouteValueDictionary を取るシグネチャで RedirectToAction を使用することをお勧めします。リダイレクト先のメソッドは、コントローラーの ValueProvider から値を取得できる必要があります。次のようになります。

public ActionResult Saved( int id )
{
    var reportParams = db.Reports.SingleOrDefault( r => r.ID == id );
    if (reportParams == null)
       ...handle error...

    var routeValues = ParamsToRouteValueDictionary( reportParams );

    return RedirectToAction( reportParams.Action, reportParams.Controller, routeValues );
}

private RouteValueDictionary ParamsToRouteValueDictionary( object parameters )
{
     var values = new RouteValueDictionary();
     var properties = parameters.GetType().GetProperties()
                                .Where( p => p.Name != "Action" && p.Name != "Controller" );
     foreach (var prop in properties)
     {
         values.Add( prop.Name, prop.GetValue(parameters,null) );
     }

     return values;
}

編集

メソッドのパラメーターとしてフィルターモデルを使用すると、実際には簡単になる場合があります。アクションの GET バージョンと POST バージョンだけが必要です。

 [ActionName("People")]
 [AcceptVerbs( HttpVerbs.Get )]
 public ActionResult PeopleDisplay( SearchModel filter )
 {
     return People( filter );
 }

 [AcceptVerbs( HttpVerbs.Post)]
 [ValidateAntiForgeryToken]
 public ActionResult People( SearchModel filter )
 {
     ....
 }

次に、フィルター パラメーター (名前別)、アクション ("People")、およびコントローラーをレポート用にデータベースに格納します。リダイレクトの結果は GET を使用して PeopleDisplay メソッドに送信されます。PeopleDisplay メソッドは、正しいパラメーターを指定して People メソッドを呼び出すだけです。フォームから投稿すると、People メソッドが直接呼び出されます。2 つの方法を使用すると、CSRF 防止メカニズムを使用できます。アクセスを制限したい場合は、TempData でフラグを使用して、リダイレクト メカニズムを介してのみ GET アクションが呼び出されるようにすることができます。

編集終了

別の方法として、使用されているビューを単純に保存し、リダイレクトを行う代わりに、適切なビューをレンダリングするだけです。考慮すべきことの 1 つは、リダイレクトを実行するとすべてのパラメーターを含む URL が作成されるのに対し、ビューをレンダリングすると URL がそのまま残り、レポートの作成時に使用された URL と同じビューが表示されることです。 .

于 2009-05-05T16:18:24.797 に答える
0

RedirectToAction メソッドを使用して、ルート値とともに、任意のコントローラーの特定のアクション メソッドに 301 リダイレクトを発行できます。

ReportMeta meta = _reportDataAccess.Get(id);
return RedirectToAction(meta.Action, meta.Controller, meta.RouteData);

これらの値は次のようなものです。

meta.Action = "Bar";
meta.Controller = "Foo";
meta.RouteData = new {
    // possibly settings for the grid
    start = DateTime.Min,
    end = DateTime.Now,
    sort = "Date"
    // you get the idea
};

もちろん、これですぐにわかる問題は、コントローラー/アクション メソッドが時間の経過とともに変化したときに何が起こるかということです。レポート データは無効になります。しかし、おそらくあなたはすでにそれを考えていたでしょう。

于 2009-05-05T16:16:39.013 に答える